【问题标题】:Node/Express: Cannot set headers after they are sent to the clientNode/Express:在将标头发送到客户端后无法设置标头
【发布时间】:2020-08-28 20:47:42
【问题描述】:

我在下面的代码中尝试使用 Mongo DB 中的凭据验证用户:

{
  validate: async function (email, password, res) {
    console.log('Inside validate method');

    try {
      var dbUserObj = await User.findOne({ email: email }, (err, user) => {

        console.log('Inside validate method111111');

        if (err) {
          return res.status(500).send('Error on the server.');
        }

        console.log('Inside validate method 22222');

        if (!user) {
          return res.status(404).send('No user found.');
        }

        console.log('Inside validate method33333');

        var passwordIsValid = bcrypt.compareSync(password, user.password);

        console.log('Is Valid Password :: ' + passwordIsValid);

        if (!passwordIsValid) {
          return res.status(401).send({
            auth: false,
            token: null
          });
        }
      });
    } catch (e) {

    }

    console.log('DDDDBBBB USSSERRRR :::' + dbUserObj);
    return dbUserObj;
  }
}

下面的代码调用了 validate 方法:

var auth = {

login: function(req, res,next) {

 console.log('Inside login');
var email = req.body.email || '';
var password=req.body.password || '';
console.log('Before validate user');
// Fire a query to your DB and check if the credentials are valid
var dbUserObj = auth.validate(email,password,res);

if (!dbUserObj) { // If authentication fails, we send a 401 back
  res.status(401);
  res.json({
    "status": 401,
    "message": "Invalid credentials"
  });
  return;
}

if (dbUserObj) {      
  res.send(genToken(dbUserObj));

}

}

每当出现密码不正确的情况时,我都会收到错误消息:

错误 [ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置标头

无法真正解决问题。

【问题讨论】:

  • 你是如何使用这个功能的?似乎您的端点处理程序在此调用完成之前返回,因此出现错误。
  • 你的函数有 2 个点...一个如果密码无效,另一个...你不能这样做...即使你编码return res.send函数继续.. ..
  • 调用 validate() 后做什么?如果您在之后的某个时间执行res.send(),这可能是问题所在,因为您在返回 401 时已经这样做了。
  • 用调用函数编辑原帖

标签: node.js express mongoose


【解决方案1】:

调用你的validate()的路由需要接受来自express的the next callback parameter,否则框架假定当异步函数返回时(发生在第一个await表达式处),它已经完成了所有的工作并且在到那时,它会继续路由到默认错误处理,在您的数据库查询恢复 validate 中的异步控制流之前发送 404。

当您的路由处理程序接受next 参数时,表示表示该路由将异步处理,您可以做3 件事中的1 件事:

  1. 如果您已经发送了回复(在这种情况下您总是这样做),请不要致电 next()
  2. 如果您不发送响应并希望将响应处理委托给其余路由,请不带参数调用 next()
  3. 如果您想将响应处理委托给剩余的中间件,该中间件将为您处理错误报告和响应,请致电 next(error)

【讨论】:

  • @suvikc login: async functionvar dbUserObj = await auth.validate(email,password,res);
  • @Patrick 成功了,谢谢。你能在这里解释一下是什么问题吗?
  • @suvikc async functions 返回一个Promise
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-27
  • 1970-01-01
  • 2021-03-05
  • 2020-11-14
  • 2020-11-02
  • 2021-06-18
相关资源
最近更新 更多