从Node.js后端向iPhone前端发送JSON错误:“错误:发送后无法设置标头。”

从Node.js后端向iPhone前端发送JSON错误:“错误:发送后无法设置标头。”

问题描述:

我是Node.js的新手。我使用它作为iPhone客户端的服务器后端。我打电话一个POST与JSON:{姓: “鲍勃”,电子邮件:[email protected]}从Node.js后端向iPhone前端发送JSON错误:“错误:发送后无法设置标头。”

Node.js的代码如下所示(使用Express和猫鼬):

var User = new Schema({ 
    firstname : { type: String, required: true} 
    , email  : { type: String, required: true, unique : true} 

}); 
var User = mongoose.model('User', User); 

而对于POST,

app.post('/new/user', function(req, res){ 

    // make a variable for the userData 
    var userData = { 
     firstname: req.body.firstname, 
     email: req.body.email 
    }; 

    var user = new User(userData); 

    //try to save the user data 
    user.save(function(err) { 
     if (err) { 
      // if an error occurs, show it in console and send it back to the iPhone 
      console.log(err); 
      res.json(err); 
     } 
     else{ 
      console.log('New user created'); 
     } 
    }); 

    res.end(); 
}); 

现在,我试图用相同的电子邮件创建重复的用户。由于电子邮件上的“唯一”约束,我期望这会引发错误 - 它会这样做。

但是,node.js进程因“错误:发送后无法设置标头”而死亡。

我希望能够在诸如这些情况下将消息发送回iPhone客户端。例如,在上面,我希望能够发回JSON到iphone,说新用户创建的结果(成功或失败)。

谢谢!

+0

注释掉固定这个问题的最后res.end。所以也许res.send和res.json自己调用res.end? – kurisukun 2013-02-14 08:30:18

+0

我觉得没有。在你的代码中,如果发生错误,'res.end'首先被调用,而不是'res.json',因为你的代码是异步执行的。 – balazs 2013-02-14 09:06:12

这是因为你的代码的异步性质。 res.end()user.save的回调函数之前运行,您应该将res.end()置于该回调中(最后)。

这样:

user.save(function(err) { 
    if (err) { 
     // if an error occurs, show it in console and send it back to the iPhone 
     console.log(err); 
     return res.json(err); 
    } 
    console.log('New user created'); 
    res.end(); 
}); 

使用适当的HTTP状态发送你的错误,你有充足的4XX做到这一点。

res.json(420, err); 

这样的话,你就只能在解析你的HTTP获取消息,用jQuery它给像:

jQuery.ajax({ 
    ... 
    error: function (xhr, ajaxOptions, thrownError) { 
    if(xhr.status == 420) { 
     JSON.parse(xhr.responseText); 
    } 
    }