NodeJS 发布请求后,节点被压缩

wlwcrazw  于 2022-12-03  发布在  Node.js
关注(0)|答案(1)|浏览(131)

我有以下index.js文件:

var express = require('express');
const { body, validationResult } = require('express-validator');
var router = express.Router();
const bcrypt = require('bcryptjs');
const User = require('../models/user');

router.get('/', function(req, res, next) {
  res.render('index', { title: 'Messages' });
});
router.get('/sign-up', function(req, res, next) {
  res.render('sign-up', {title: 'sign up'})
});
router.post(
  '/sign-up', 
  body('username', 'Username is required').trim().isLength({min:1}).escape(), 
  body('password', 'Password is required').trim().isLength({min:1}).escape(),
  body('confPassword').custom((value, { req }) => {
    if (value !== req.body.password) {
      throw new Error('Password confirmation does not match password');
    }
    return true;
  }),
  (req, res, next) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.render('sign-up', {title: 'Sign-up', errors: errors.errors})
    }
    User.find({ 'username': req.body.username}).exec(function(err, existingUser){
      if (err) {
        return next(err)
      }
      if (existingUser) {
        console.log(req.body.username)
        console.log(existingUser)
        res.render('sign-up', {title: 'Sign-up', error: ` ${req.body.username} already exists in the system. Please choose another username`})
      }
    })
    bcrypt.hash(req.body.password, 10, (err, hashedPassword) => {
      if (err) {
        return next(err)
      }
      const user = new User({
        username: req.body.username,
        password: hashedPassword
      }).save(err=> {
        if (err) {
          return next(err);
        }
        res.redirect("/")
      })
    })  
  }
)
router.get('/sign-in', function(req, res, next) {
  res.render('sign-in', {})
})

module.exports = router;

查看来自/sign-up的POST--当我输入用户名和匹配的密码时--用户被保存在MongoDB中并且没有错误。
但是,如果我的密码没有填写或不匹配,或用户存在于mongoDB中,应用程序将崩溃,仍然会创建一个用户并将其保存到MongoDB中。
这是我得到的错误:

node:events:504
  throw er; // Unhandled 'error' event
  ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:371:5)

at ServerResponse.setHeader (node:_http_outgoing:576:11)

at ServerResponse.header (/Users/adi/programming/learning/myProjects/members-only/node_modules/express/lib/response.js:767:10)

at ServerResponse.location (/Users/adi/programming/learning/myProjects/members-only/node_modules/express/lib/response.js:884:15)

at ServerResponse.redirect (/Users/adi/programming/learning/myProjects/members-only/node_modules/express/lib/response.js:922:18)

at /Users/adi/programming/learning/myProjects/members-only/routes/index.js:51:13

at /Users/adi/programming/learning/myProjects/members-only/node_modules/mongoose/lib/model.js:5207:18

at processTicksAndRejections (node:internal/process/task_queues:78:11)

Emitted 'error' event on Function instance at:

at /Users/adi/programming/learning/myProjects/members-only/node_modules/mongoose/lib/model.js:5209:15

at processTicksAndRejections (node:internal/process/task_queues:78:11) {
code: 'ERR_HTTP_HEADERS_SENT'
}
[nodemon] app crashed - waiting for file changes before starting...
w6lpcovy

w6lpcovy1#

您的post处理程序需要类似于

router.post(
  "/sign-up",
  body("username", "Username is required").trim().isLength({ min: 1 }).escape(),
  body("password", "Password is required").trim().isLength({ min: 1 }).escape(),
  body("confPassword").custom((value, { req }) => {
    if (value !== req.body.password) {
      throw new Error("Password confirmation does not match password");
    }
    return true;
  }),
  (req, res, next) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      res.render("sign-up", { title: "Sign-up", errors: errors.errors });
      return;
    }
    User.find({ username: req.body.username }).exec((err, existingUser) => {
      if (err) {
        return next(err);
      }
      if (existingUser) {
        console.log(req.body.username);
        console.log(existingUser);
        res.render("sign-up", {
          title: "Sign-up",
          error: ` ${req.body.username} already exists in the system. Please choose another username`,
        });
        return;
      }
      bcrypt.hash(req.body.password, 10, (err, hashedPassword) => {
        if (err) {
          return next(err);
        }
        new User({
          username: req.body.username,
          password: hashedPassword,
        }).save((err) => {
          if (err) {
            return next(err);
          }
          res.redirect("/");
        });
      });
    });
  },
);

所以

  • 在回调中适当地嵌套内容(仅在验证不存在现有用户后尝试对密码进行哈希运算并创建新用户等)
  • 并且每个res.render后面都跟有一个return,所以只需要一次尝试就可以呈现结果。

正如我在评论中提到的,考虑使用async/await而不是回调来获得更简单的代码。

相关问题