MEVN Stack перенаправляет на домашнюю страницу после пения

В настоящее время я застрял в создании функции регистрации сайта. Я использую стек MEVN, и мне удалось заставить мой внешний интерфейс работать с моей базой данных, но как только это будет сделано, я получаю

cannot POST users/signup

Позвольте мне показать вам соответствующий код:

router.post('/signup', (req, res, next) => {
  //Verify if user email is associated with an account.
  User.find({email: req.body.email})
    .exec()
    .then(user => {
      //Returns message if user email is associated with an account.
      if(user.length >= 1) {
        getCode.fourHundred(res, 409, 
          'This email is already associated with an account.');
      } else { //If email is not found, makes a hashed password value. 
        if(req.body.password !== 'undefined') {
          bcrypt.hash(req.body.password, 10, (err, hash) => {
            if(err) {
              getCode.fiveHundred(res, err);
            } else {
              //If no errors occur, creates a new user. 
              const user = new User({
                _id: new mongoose.Types.ObjectId(),
                firstName: req.body.firstName,
                lastName: req.body.lastName,
                email: req.body.email,
                password: hash
              });
              // Saves user information to Database. 
              user.save()
              .then(result => {
                console.log(result);
                getCode.twoHundred(res, 201, 'User created')
                return res.redirect(301, 'localhost:8080')
              })
              .catch(getCode.fiveHundred(res, err))
            }
          });
        } 
      }
    });
});

Моя передняя часть выглядит следующим образом:

<template>
  <main class="container">
    <h1> Sign Up</h1>
    <form class="grid-container" action="/users/signup" method="POST">
      <label class="label" for="first-name">First Name:</label>
      <input
        id="first-name"
        type="text"
        class="first-name input form-control"
        placeholder="First Name"
        v-model="firstName"
        required>

      <label class="label" for="last-name" >Last Name:</label>
      <input id="last-name"
         type="text"
         class="last-name input form-control"
         placeholder="Last Name"
         v-model="lastName"
         required>
      <label class="label" for="email" >Email:</label>
      <input id="email"
         type="email"
         class="email input form-control"
         placeholder="[email protected]"
         v-model="email"
         required>
      <label class="label" for="password">Password:</label>
      <input id="password"
         type="password"
         class="password input form-control"
         placeholder="Password"
         v-model="password"
         required>
      <div class="button-grid">
        <button
          class="button"
          type="submit"
          @click="signUp">
            Sign Up
        </button>
      </div>

    </form>
  </main>
</template>

<script>
import AuthenticationService from '@/services/AuthenticationService.js'

export default {
  name: 'SignUp',
  data () {
    return {
      firstName: '',
      lastName: '',
      email: '',
      password: ''
    }
  },
  methods: {
    async signUp () {
      const response = await AuthenticationService.signUp({
        firstName: this.firstName,
        lastName: this.lastName,
        email: this.email,
        password: this.password
      })
      console.log(response)
      setTimeout(() => this.redirect(), 1000)
    },
    redirect () {
      this.$router.push({ name: 'BuyAndSell' })
    }
  }
}
</script>

Я использую axios для подключения внешнего интерфейса к внутреннему.


export default () => axios.create({
  baseURL: 'http://localhost:3000/'
})
import api from '@/services/api'

export default {
  signUp (credentials, res) {
    return api().post('/users/signup', credentials)
  }
}

Я пробовал перенаправлять через Vue и пробовал через экспресс, но ничего не добился.

Редактировать: я также добавляю этот код, потому что это некоторые функции, которые я реорганизовал, чтобы немного очистить свой код.

const getFiveHundredErrors = (res, err) => {
    console.log(err);
    return res.status(500).json({
      error: err
    });
  };

  const getfourHundredErrors = (res, code, message) => {
    return res.status(code).json({
      message: message
    })
  };

  const getTwoHundredSuccessCodes = (res, code, output, token) => {
    return res.status(code).json({
      output: output,
      token: token || null
    })

  }

  module.exports = { 
    fiveHundred: getFiveHundredErrors, 
    fourHundred: getfourHundredErrors, 
    twoHundred: getTwoHundredSuccessCodes }

Это файл app.js. Я получаю в своей консоли ошибку 500, которая, вероятно, связана с .catch (), может быть, ошибка есть? Но я не уверен, как получить код для перенаправления обратно на домашнюю страницу после создания пользователей. Кроме того, несмотря на то, что пользователи создаются, статус 200 мне тоже не показывается.

const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const path = require('path');

const app = express();
const port = process.env.PORT || 3000;

const userRoutes = require('./api/routes/users');
const productRoutes = require('./api/routes/products');
const savedItemsRoutes = require('./api/routes/savedItems');

//I removed the mongodb.connect function to avoid exposing that info, even though I have the password stored in a .env file. 

//Middleware.
app.use(morgan('dev'))
app.use('/uploads', express.static('uploads'))
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(cors());

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 
  'Origin, X-Requested-Width, Content-Type, Accept, Authorization'
  );
  if(req.method === 'OPTIONS') {
    res.header('Access-Control-Allow-Methods', 
    'PUT', 'POST', 'PATCH', 'DELETE', 'GET');
    return res.status(200/json({}));
  }
  next();
});

// Request Handling Routes. 
app.use('/users', userRoutes);
app.use('/products', productRoutes);
app.use('/savedItems', savedItemsRoutes);

Другая проблема: я вроде как понимаю, что здесь происходит, но пока не знаю, где это можно исправить. Я знаю, что должен вернуть некоторый res.status после отправки исходного ответа, но я просто немного смущен тем, каков поток моего кода, и я пытаюсь понять, куда меня ведет сообщение об ошибке, но я м просто невежественный в этот момент.

(node:28036) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:535:11)
    at ServerResponse.header (/Users/edgarnegron/Projects/llevatelopr/server/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/Users/edgarnegron/Projects/llevatelopr/server/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/Users/edgarnegron/Projects/llevatelopr/server/node_modules/express/lib/response.js:267:15)
    at getTwoHundredSuccessCodes (/Users/edgarnegron/Projects/llevatelopr/server/api/routes/users.js:112:20)
    at /Users/edgarnegron/Projects/llevatelopr/server/api/routes/users.js:40:17
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

person Edgar Armando Negrón Rabell    schedule 23.02.2020    source источник
comment
Этот код не относится к ошибке. Можете ли вы показать, где вы обрабатываете свой маршрут users/signup в Express? Что-то вроде app.post('users/signup', ... Это сообщение в основном означает, что такого обработчика маршрута не существует.   -  person Dan    schedule 23.02.2020
comment
@dan Да, я понимаю, что ты имеешь в виду. Тем не менее, я могу видеть журналы консоли всякий раз, когда я создаю пользователя в своей базе данных, и когда я перехожу к мангусту, создаются пользователи. Я не уверен, как сделать перенаправление после этого на мою домашнюю страницу.   -  person Edgar Armando Negrón Rabell    schedule 23.02.2020
comment
@dan Я опубликовал все это, но ошибка формата не отобразила это, я исправил это сейчас. Спасибо, что нашли время ответить на мой вопрос.   -  person Edgar Armando Negrón Rabell    schedule 23.02.2020
comment
Вы говорите, что создаете пользователя, хотя Express говорит, что не может найти маршрут, или вы создаете пользователя каким-то другим способом? Вы также должны показать любые /users маршруты.   -  person Dan    schedule 23.02.2020
comment
Да, в коде, который я написал для маршрута /signup, я вижу, что console.log(результат) из .then() распечатывается на моей консоли, а моя база данных mongoDB заполняется пользователями. позвольте мне показать вам мой файл app.js. Я предполагаю, что ошибка связана с утилитами кода состояния getCode, которые я создал.   -  person Edgar Armando Negrón Rabell    schedule 23.02.2020
comment
Проблема в том, что это невозможно: если он не может найти маршрут, он не может запустить код маршрута. Я вижу, что происходит сейчас. При ближайшем рассмотрении кажется, что вы на самом деле делаете две вещи при отправке формы: 1 из щелчка (метод signUp: это, вероятно, создание пользователя, хотя я не вижу код службы) и 1 из формы action. Это плохой дизайн по двум причинам. Вы не должны создавать 2 отдельных вызова, подобных этому, и вы не должны использовать действие формы таким образом, иначе вы покинете свое одностраничное приложение. Существует также перенаправление внешнего интерфейса и внутреннего интерфейса. Это все противоречит самому себе   -  person Dan    schedule 23.02.2020
comment
@dan спасибо, что указали мне на это. Честно говоря, я не Back End-разработчик, и я очень ценю ваши отзывы. Что было бы лучшей практикой. Я должен устранить действие и какое перенаправление следует удалить из моего кода. Я действительно не думал о том, чтобы оставить оба там, а просто слепо пытался увидеть, что сработает. Я определенно не должен был пытаться использовать оба способа одновременно.   -  person Edgar Armando Negrón Rabell    schedule 23.02.2020
comment
Полностью удалите действие/метод формы. Это то, что уводит вас от SPA (и к неправильному маршруту, показывающему сообщение об ошибке). Как правило, вы не используете действие формы с SPA, таким как Vue, потому что оно выводит вас из приложения. Ваша служба аутентификации успешно создает пользователя, поэтому все должно быть в порядке, если вы видите сообщение console в методе signUp.   -  person Dan    schedule 24.02.2020
comment
@dan большое спасибо. Я исправил проблему, у меня есть еще одна, над которой я тоже некоторое время работал, я пытаюсь исправить ее самостоятельно, но если бы вы также могли намекнуть мне, что это может быть, я был бы очень благодарен .   -  person Edgar Armando Negrón Rabell    schedule 24.02.2020
comment
Сначала позвольте мне представить это как ответ, который вы должны принять.   -  person Dan    schedule 24.02.2020
comment
@dan ^^ Очевидно, исправлено благодаря вашей помощи. Прежде чем вы написали это сообщение, я подумал, что это то, что я должен был сделать в соответствии с вашим предложением. Большое спасибо, я пытался исправить это почти неделю. Ты живая заставка.   -  person Edgar Armando Negrón Rabell    schedule 24.02.2020
comment
Пожалуйста. Я отредактировал ответ на ваш второй вопрос   -  person Dan    schedule 24.02.2020


Ответы (1)


Проблема в том, что действие формы уводит вас от SPA по неверному маршруту. И вы на самом деле делаете две вещи при отправке формы:

1) Действие click вызывает метод signUp. Это создает пользователя, хотя мы не можем видеть код службы.

2) Действие формы

Это плохой дизайн по двум причинам. Вы не должны создавать 2 отдельных вызова, подобных этому, и вы не должны использовать действие формы таким образом, иначе вы покинете свое одностраничное приложение. Существует также перенаправление внешнего интерфейса и внутреннего интерфейса. Полностью удалите действие/метод формы. Это то, что уводит вас от SPA (и к неправильному маршруту, показывающему сообщение об ошибке). Как правило, вы не используете действие формы с SPA, потому что оно выводит вас из приложения.

вопрос 2

Измените код после сохранения на:

user.save()
  .then(result => {
    return res.status(201).send(result);
  })

Это установит статус и отправит обратно пользователя, которого вы только что создали, если save также вернет его. 301 не нужен.

person Dan    schedule 23.02.2020