快速重定向错误:发送后无法设置标头

时间:2014-10-14 23:27:48

标签: node.js express

当此代码命中重定向行时,它会抛出“在发送错误后无法设置标头”并且不会重定向。我对没有完全理解标题以及如何表达与它们一起工作感到内疚。 This link about this error让我感到困惑,可能是因为我对正在发生的事情没有基本的了解。此外,我知道这是一种天真的身份验证方法,但我只是想让基本的东西工作。

    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")
      }
    })

更新:谢谢你@Brendan Ashworth我错过了一个显而易见的其他内容,我现在已经添加了,不再收到错误。

但是这一行不会改变我页面的内容

res.sendfile('./public/admin/views/tunes.html')

在我用auth检查包装它之前它已经工作了

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') 
})

}

最终更新!!我需要的最后一件事是在发送文件后处理重定向客户端。简单的身份验证现在完美无缺!

    $http.post('/api/login', $scope.auth).success(function() {
        window.location.href = '/admin'
    })

1 个答案:

答案 0 :(得分:9)

错误Can't set headers after they are sent error的解释:

所有HTTP响应都遵循以下基本结构:

.. Response Line ..
.. Headers ..

.. Body ..

如果您想重定向用户,首先Response Line将使用重定向代码(例如300)发送,然后Headers将与Location: xxx标头一起发送。

然后,我们最终可以发送一个正文(不是在重定向的情况下,但一般情况下)。但是 - 对于您的代码 - 您正在发送Body响应然后尝试重定向用户。由于标题(和响应行)都已经发送(因为你发送了正文),它不能在正文后发送更多标题。

您的代码中的一个示例是:

app.get('/admin', function(req, res) {
    if (auth.date) {
        res.sendfile('./public/admin/views/tunes.html')
    }
    res.redirect('/admin/login')
})

如果我假设正确,您实际上想在return电话后res.sendfile()。如果auth.date是真实的,那么您将发送一个文件(即正文回复),然后提供重定向代码 - 这不起作用。