node.js 快速重定向错误:发送后无法设置标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26372080/
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 redirect error: can't set headers after they are sent
提问by azium
When this code hits the redirect line it throws the 'Can't set headers after they are sent error' and doesn't redirect. I'm guilty of not fully understanding headers and how express works with them. This link about this erroris confusing me a bit, probably because I don't have a basic enough understanding of what's going on. Also, I know this is a bit of a naive approach to authenticating, but I'm just trying to get basic things to work.
当此代码命中重定向行时,它会抛出“发送错误后无法设置标头”并且不重定向。我对没有完全理解标题以及 express 如何与它们一起工作感到内疚。这个关于这个错误的链接让我有点困惑,可能是因为我对发生的事情没有足够的基本了解。另外,我知道这有点幼稚的身份验证方法,但我只是想让基本的东西发挥作用。
app.post('/api/login', function(req, res) {
if (req.body.password === auth.password) {
auth.date = new Date()
res.redirect('/admin')
} else {
console.log("wrong pw")
}
})
UPDATE : thank you to @Brendan Ashworth I missed an obvious else, which I've added now and no longer get the error.
更新:感谢@Brendan Ashworth 我错过了一个明显的其他问题,我现在已经添加了,不再出现错误。
However this line doesn't change the contents of my page
但是这一行不会改变我页面的内容
res.sendfile('./public/admin/views/tunes.html')
It worked before I wrapped it with the auth check
在我用身份验证检查包装它之前它起作用了
var auth = require('../config/auth')
module.exports = function(app) {
/*
* CONTENT API
*/
//...
/*
* Admin Routes
*/
app.get('/admin/login', function(req, res) {
res.sendfile('./public/admin/views/login.html')
})
app.post('/api/login', function(req, res) {
if (req.body.password === auth.password) {
auth.date = new Date()
res.redirect('/admin')
} else {
res.json({message: 'Wrong password!'})
}
})
app.get('/admin', function(req, res) {
if (auth.date) {
res.sendfile('./public/admin/views/tunes.html')
console.log("test") //
} else { //added else
res.redirect('/admin/login')
}
})
app.get('/admin/:url', function(req, res) {
if (auth.date) {
res.sendfile('./public/admin/views/' + req.params.url + '.html')
} else { //added else
res.redirect('/admin/login')
}
})
// frontend routes
// route to handle all angular requests
app.get('*', function(req, res) {
res.sendfile('./public/views/index.html')
})
}
}
FINAL UPDATE!! The last thing I needed was to handle the redirect client side after sending the file. Simple authentication works perfectly now!
最后更新!!我需要做的最后一件事是在发送文件后处理重定向客户端。简单的身份验证现在可以完美运行!
$http.post('/api/login', $scope.auth).success(function() {
window.location.href = '/admin'
})
回答by Brendan
An explanation of the error Can't set headers after they are sent error:
错误的解释Can't set headers after they are sent error:
All HTTP responses follow this basic structure:
所有 HTTP 响应都遵循以下基本结构:
.. Response Line ..
.. Headers ..
.. Body ..
If you want to redirect a user, first the Response Linewill be sent with a redirect code (lets say 300), then the Headerswill be sent with a Location: xxxheader.
如果您想重定向用户,首先Response Line将发送一个重定向代码(比如说 300),然后Headers发送一个Location: xxx标头。
Then, we can finally send a body (not in the case of a redirect, but in general). However - in the case with your code - you are sending a Bodyresponse thentrying to redirect the user. Since the headers (and response line) have both already been sent (because you sent the body), it can't send more headers after the body.
然后,我们终于可以发送一个正文(不是在重定向的情况下,而是在一般情况下)。但是 - 在您的代码的情况下 - 您正在发送Body响应然后尝试重定向用户。由于标头(和响应行)都已发送(因为您发送了正文),因此无法在正文之后发送更多标头。
An example of this in your code would be:
您的代码中的一个示例是:
app.get('/admin', function(req, res) {
if (auth.date) {
res.sendfile('./public/admin/views/tunes.html')
}
res.redirect('/admin/login')
})
If I'm assuming right, you actually want to returnafter the res.sendfile()call. If auth.dateis truthy, then you'll be sending a file (i.e. body response) and then giving a redirect code - that doesn't work.
如果我假设是对的,您实际上想return在res.sendfile()通话后。如果auth.date是真的,那么您将发送一个文件(即正文响应),然后给出一个重定向代码——这是行不通的。

