我在路由的控制台中遇到了一些错误。快速路线如下:
router.get('/getInfo/:id', function(req, res, next) {
return passport.authenticate('jwt', {session: false}, function(err, account, info) {
if (err) { return next(err);}
if (!account) {
new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){
return res.status(200).send(acc.toJSON());
});
}
if(account._id != req.params.id) {
new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){
return res.status(200).send(acc.toJSON());
});
}
else {
new Account({_id: req.params.id}).fetch().then(function(acc){
return res.status(200).send(acc.toJSON());
});
}
})(req, res, next);
});
错误消息仅在我未通过身份验证时出现 - 它说
Unhandled rejection Error: Can't set headers after they are sent.
...
at null.<anonymous> (/-----/routes/users.js:61:27)
第 61 行是块中的 res.status(200(..,其中 (account._id != req.params.id(。
代码背后的想法是,如果您请求有关不是您的用户的信息(由 jwt 验证(,您只会获得一些信息 - 现在只有"first_name"。如果您请求有关您自己的信息,则会看到所有信息。
最让我烦恼的是,每次调用路由时,我仍然会得到有效的响应。服务器不会崩溃/拒绝加载/..- 我得到了我所期望的。
我认为它来自对承诺的不当使用
问题是当你写这个
if (!account) {
new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){
return res.status(200).send(acc.toJSON());
});
}
您实际上并没有从函数返回,而是创建一个新帐户并获得承诺的res.status(200)...
执行,但随后您继续执行下一行if ... else ...
保证您也获得另一个res.status(200)...
您确实正在尝试设置两次标题,因此出现错误。
要解决此问题,您有几种解决方案
(1( 在 ifs 中的所有行中添加 ˋreturn'
router.get('/getInfo/:id', function(req, res, next) {
return passport.authenticate('jwt', {session: false}, function(err, account, info) {
if (err) { return next(err);}
if (!account) {
return new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){
return res.status(200).send(acc.toJSON());
});
}
if(account._id != req.params.id) {
return new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){
return res.status(200).send(acc.toJSON());
});
}
else {
return new Account({_id: req.params.id}).fetch().then(function(acc){
return res.status(200).send(acc.toJSON());
});
}
})(req, res, next);
});
(2( 链接 ifs,以确保每次调用只执行一次
router.get('/getInfo/:id', function(req, res, next) {
return passport.authenticate('jwt', {session: false}, function(err, account, info) {
if (err) { return next(err);}
if (!account) {
new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){
return res.status(200).send(acc.toJSON());
});
} else if(account._id != req.params.id) {
new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){
return res.status(200).send(acc.toJSON());
});
} else {
new Account({_id: req.params.id}).fetch().then(function(acc){
return res.status(200).send(acc.toJSON());
});
}
})(req, res, next);
});
(3(或者你稍微重组一下你的代码,使其更符合承诺的意图。实际上,您有3种不同的方法来创建帐户,但只有一种方法可以结束通话。我会更明确地说明这一点。那会给出类似的东西
router.get('/getInfo/:id', function(req, res, next) {
return passport.authenticate('jwt', {session: false}, function(err, account, info) {
if (err) { return next(err);}
let createAccountPromise;
if (!account) {
createAccountPromise = new Account({_id: req.params.id}).fetch({columns: ['first_name']});
} else if(account._id != req.params.id) {
createAccountPromise = new Account({_id: req.params.id}).fetch({columns: ['first_name']});
} else {
createAccountPromise = new Account({_id: req.params.id}).fetch();
}
return createAccountPromise
.then(function(acc){
return res.status(200).send(acc.toJSON());
});
})(req, res, next);
});