尽管发送了状态代码,为什么会出现“错误:发送后无法设置标头”?

时间:2015-04-28 14:54:05

标签: node.js http express passport.js

这是我的代码:

app.post('/register', function(req, res){
  var user = new User(req.body);
  if (req.body.password.length <= 5){ res.status(400).send('error: password must be longer'); }
  if (req.body.username.length <= 3){ res.status(400).send('error: username must be longer'); }
  User.findOne({
    username: req.body.username
  }, function(err, userr){
       if(err) {res.status(400).send(err); }
       if (userr){res.status(400).send('error: user already exists'); }
       user.save(function(err, user){
         if (err){ res.status(400).send('couldn\tt save fo sum rezon'); }              
         if (user) { res.send(user); }
       });
    });
});

这是我的错误:

home/michael/passport-local-implementation/node_modules/mongoose/node_modules/mpromise/lib/promise.js:108
  if (this.ended && !this.hasRejectListeners()) throw reason;
                                                      ^
Error: Can't set headers after they are sent.

我很困惑我不止一次发送标题的位置?如果满足其中一个条件,或者如果没有满足条件,那么此代码不应该停止执行,那么只需渲染用户吗?

奖励积分如果有人可以给我资源,可以在哪里阅读有关快速路由工作方式的详细信息!

2 个答案:

答案 0 :(得分:2)

以以下行为例:

if (req.body.password.length <= 5){ res.status(400).send('error: password must be longer'); }

如果条件满足,express将发送响应,但函数不会返回,因此下一行被评估等等。

您只需添加return;即可确保在已发送回复时该函数返回。

这里有奖励积分;)express routing

<强>更新

如果您不使用return,则应始终使用else

  ...
  var user = new User(req.body);
  if (req.body.password.length <= 5){ res.status(400).send('error: password must be longer'); }
  else if (req.body.username.length <= 3){ res.status(400).send('error: username must be longer'); } 
  else { // include the rest of your function code here... }

这样,只有在if失败时才会评估其余代码。

答案 1 :(得分:1)

添加到john's answer

如果在你的例子中:

 if (req.body.password.length <= 5){ res.status(400).send('error: password must be longer'); }
  if (req.body.username.length <= 3){ res.status(400).send('error: username must be longer'); }

如果req.body.password.length小于或等于3。

两个条件都满足,并且在第一个if表达式发送响应,然后它在尝试满足第二个条件时发送响应。但是响应,因此它的标题已经发送(如错误所示)。

快递发送方法包括以下任务:

  1. 设置标题
  2. 设置回复正文
  3. 结束回复(res.end)
  4. 因此res.send结束响应,因此您无法在发送后发送回复。

    你宁可选择发送这样的回复

    if (req.body.password.length <= 5){ 
        res.status(400).send('error: password must be longer'); 
      } else if (req.body.username.length <= 3){ 
        res.status(400).send('error: username must be longer'); 
      }