Express redirect error: can't set headers after they are sent

ε祈祈猫儿з 提交于 2020-07-18 09:47:27

问题


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 error is 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.

    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.

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

回答1:


An explanation of the error Can't set headers after they are sent error:

All HTTP responses follow this basic structure:

.. Response Line ..
.. Headers ..

.. Body ..

If you want to redirect a user, first the Response Line will be sent with a redirect code (lets say 300), then the Headers will be sent with a Location: xxx header.

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 Body response then trying 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.

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 return after the res.sendfile() call. If auth.date is truthy, then you'll be sending a file (i.e. body response) and then giving a redirect code - that doesn't work.



来源:https://stackoverflow.com/questions/26372080/express-redirect-error-cant-set-headers-after-they-are-sent

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!