我在路由器的控制台中遇到了一些错误。快递路线如下:
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行是带有(account._id!= req.params.id)的块中的res.status(200)..
代码背后的想法是,如果您要求的用户信息不是您(由jwt验证),您只能获得一些信息 - 现在只有&#39; first_name&#39;。如果您要求提供有关您自己的信息,您会看到所有信息。
最让我烦恼的是每次打电话给路线时我都会得到有效的回复。服务器没有崩溃/拒绝加载/ .. - 我得到了我期望的结果。
答案 0 :(得分:0)
我认为这来自对承诺的不当使用
问题在于你写这个
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)或者你稍微重构你的代码,使其更符合promises的意图。实际上,您有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);
});