node.js Express.js 路由错误:发送后无法设置标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34983520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Express.js Routing error: Can't set headers after they are sent
提问by bounty
I'm not really sure why I'm getting this error. It's a simple API built on express.js to be able to add and remove posts. The error occurs when I trigger the delete router. I've read that the error typically happens when there are two callbacks, however, I don't seem to be able find any double callbacks.
我不确定为什么会收到此错误。这是一个建立在 express.js 上的简单 API,能够添加和删除帖子。当我触发删除路由器时发生错误。我读到错误通常发生在有两个回调时,但是,我似乎无法找到任何双重回调。
_http_outgoing.js:344
throw new Error('Can\'t set headers after they are sent.');
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
at ServerResponse.header (/Users/bounty/Projects/_learning/react-express/node_modules/express/lib/response.js:718:10)
at ServerResponse.send (/Users/bounty/Projects/_learning/react-express/node_modules/express/lib/response.js:163:12)
at ServerResponse.json (/Users/bounty/Projects/_learning/react-express/node_modules/express/lib/response.js:249:15)
at /Users/bounty/Projects/_learning/react-express/server/routes/posts.js:86:9
at nextTickCallbackWith0Args (node.js:452:9)
at process._tickCallback (node.js:381:13)
Here is my posts.js router:
这是我的 posts.js 路由器:
module.exports = function(router) {
var Post = require('../models/post.js');
// middleware for the api requests
router.use(function(req, res, next) {
// do logging
console.log('something is happening.');
next(); // make sure we go to our next route and don't stop here
});
// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
// all routes here
// routes that end in /posts
router.route('/posts')
// create a Post (accessed at POST http://localhost:7777/api/posts)
.post(function(req, res) {
var post = new Post();
post.postTitle = req.body.postTitle; // set the post name (comes from request)
// save post and check for errors
post.save(function(err) {
if (err)
res.send();
res.json({ message: 'post created!' });
});
})
// get all Posts (accessed at GET http://localhost:7777/api/posts)
.get(function(req, res) {
Post.find(function(err, posts) {
if (err)
res.send();
res.json(posts);
});
});
// routes that end in /posts for specific id
router.route('/posts/:post_id')
// get the post with that id
.get(function(req, res) {
Post.findById(req.params.post_id, function(err, post) {
if (err)
res.send(err);
res.json(post);
});
})
// update the post with that id
.put(function(req, res) {
Post.findById(req.params.post_id, function(err, post) {
if (err)
res.send(err);
post.postTitle = req.body.postTitle;
// save the post
post.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'post updated!' });
});
});
})
// deletes the post with that id
.delete(function(req, res) {
Post.remove({
_id: req.params.post_id
}, function(err, post) {
if (err) {
res.send(err);
}
res.json({ message: 'post deleted!' });
});
});
}
回答by Gadi
You need to add the 'return' so that you don't reply twice.
您需要添加“返回”,以免回复两次。
// save post and check for errors
post.save(function(err) {
if (err) {
return res.send();
}
res.json({ message: 'post created!' });
});
回答by jfriend00
That particular error message is pretty much always caused because of a timing error in the handling of an async response that causes you to attempt to send data on a response after the response has already been sent.
该特定错误消息几乎总是由于处理异步响应时的计时错误导致您尝试在响应已发送后发送数据。
It usually happens when people treat an async response inside an express route as a synchronous response and they end up sending data twice.
当人们将快速路由中的异步响应视为同步响应并且他们最终发送数据两次时,通常会发生这种情况。
One place I see you would get this is in any of your error paths:
我看到你会得到这个的一个地方是在你的任何错误路径中:
When you do this:
当你这样做时:
// save post and check for errors
post.save(function(err) {
if (err)
res.send();
res.json({ message: 'post created!' });
});
If post.save()generates an error, you will do res.send()and then you will do res.json(...)after it. Your code needs to have a returnor an elseso when there's an error you don't execute both code paths.
如果post.save()产生错误,你会做res.send(),然后你会res.json(...)在它之后做。当出现错误时,您的代码需要有一个return或一个,else因此您不会同时执行两个代码路径。
回答by R.A. Lucas
So, this can happen in Express when attempting to send res.endtwice which res.sendand res.jsonboth do. In your if(err)block you'll want to return res.send()as res.sendruns asynchronously and res.jsonis getting called as well. I'm wondering if you're getting an error in your deleteroute? Hope this helps.
因此,当尝试发送res.end两次res.send并且res.json两者都发送时,这可能会在 Express 中发生。在您的if(err)块中,您将希望return res.send()asres.send异步运行并且res.json也被调用。我想知道您是否在delete路线中遇到错误?希望这可以帮助。
Best!
最好的事物!
回答by Jay Thakkar
You are using res.send()or res.json()twice in the same request
您在同一请求中使用res.send()或res.json()两次
this send the headers first, followed by body of the response and then headers again.
req.nextis usually not a function, nextis rather passed as a third argument of the middleware. Use that if you want to drop to the next middleware. (assuming you are using Express framework)
这首先发送标头,然后是响应正文,然后再次发送标头。
req.next通常不是函数,next而是作为中间件的第三个参数传递。如果您想转到下一个中间件,请使用它。(假设您使用的是 Express 框架)
回答by Seraj Ahmad
Just for the sake of completeness I will also mention that:
Sometime problem may be in a the middleware you may be using by calling
app.use.
为了完整起见,我还将提到:有时问题可能出在您可能通过调用
app.use.
After checking for obvious errors as mentioned in previous answers:
在检查之前的答案中提到的明显错误后:
You should remove all the app.usestatement then reintroduce them one by one, to find problematic module.
您应该删除所有app.use语句,然后将它们一一重新引入,以查找有问题的模块。
回答by Geek_KK
If you are using res.send() inside any loop, then you need to break it after the use of res.send(). So that it won't allow resetting of the res headers again and again.
for e.g :
for(){
if(){
res.send();
break;
}
else(){
res.send();
break;
}
}
In my case this is the problem and I solved it like this.
Hope it may help someone in future.
Thanks

