【问题标题】:Error: "Can't set headers after they are sent."错误:“发送后无法设置标题。”
【发布时间】:2015-11-13 18:10:50
【问题描述】:

我是 nodejs 及其路由系统的新手。我收到“发送后无法设置标题”。仅在 Heroku 上的生产模式下(在本地工作正常)。

// 登录 ===========================================

router.get('/', ifLoggedOut, function(req, res, next){
    res.render('login', { message: req.flash('message')});
});

router.post('/login', function(req, res, next){
    var username = req.body.username;
    var password = req.body.password;

    req.checkBody('username', 'Username field is required').notEmpty();
    req.checkBody('username', 'Password field is required').notEmpty();

    req.checkBody('password', 'Invalid Credintials').len(8, 20);
    req.checkBody('username', 'Invalid Credintials').len(4, 20);

    var errors = req.validationErrors();

    if(errors) {
    res.render('login.ejs', {errors: errors});
    } else {
        passport.authenticate('local-login', {
            successRedirect : '/list', // redirect to the secure list section
            failureRedirect : '/', // redirect back to the signup page if there is an error
            failureFlash : true // allow flash messages
        })(req, res, next);
    }
});

// 函数 ============================================= ====

function ifLoggedIn(req, res, next) {

// if user is authenticated in the session, carry on 
    if (req.isAuthenticated()) {
        return next();
    }
  console.log("cannot found in session");
  res.redirect('/');

}

function ifLoggedOut(req, res, next){
    if(req.isAuthenticated()){
        res.redirect('/list');
    }
    return next();
}


app.use('/', router);
}

// Heroku的错误日志

2015-08-20T07:37:07.490091+00:00 app[web.1]:错误:发送后无法设置标头。 2015-08-20T07:37:07.490096+00:00 app[web.1]: 在 ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11) 2015-08-20T07:37:07.490098+00:00 app[web.1]: 在 ServerResponse.header (/app/node_modules/express/lib/response.js:718:10) 2015-08-20T07:37:07.490099+00:00 app[web.1]: 在 ServerResponse.send (/app/node_modules/express/lib/response.js:163:12) 2015-08-20T07:37:07.490101+00:00 app[web.1]: 完成 (/app/node_modules/express/lib/response.js:957:10) 2015-08-20T07:37:07.490103+00:00 app[web.1]: 在 View.exports.renderFile [作为引擎] (/app/node_modules/ejs/lib/ejs.js:355:10) 2015-08-20T07:37:07.490105+00:00 app[web.1]: 在 View.render (/app/node_modules/express/lib/view.js:126:8) 2015-08-20T07:37:07.490106+00:00 app[web.1]: 在 tryRender (/app/node_modules/express/lib/application.js:639:10) 2015-08-20T07:37:07.490108+00:00 app[web.1]: 在 EventEmitter.render (/app/node_modules/express/lib/application.js:591:3) 2015-08-20T07:37:07.490109+00:00 app[web.1]: 在 ServerResponse.render (/app/node_modules/express/lib/response.js:961:7) 2015-08-20T07:37:07.490111+00:00 app[web.1]: at /app/routes/routes.js:7:7 2015-08-20T07:37:07.490112+00:00 app[web.1]: 在 Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 2015-08-20T07:37:07.490114+00:00 app[web.1]: 在下一个 (/app/node_modules/express/lib/router/route.js:131:13) 2015-08-20T07:37:07.490115+00:00 app[web.1]: 在 ifLoggedOut (/app/routes/routes.js:181:10) 2015-08-20T07:37:07.490117+00:00 app[web.1]: at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5) 2015-08-20T07:37:07.490118+00:00 app[web.1]: 在下一个 (/app/node_modules/express/lib/router/route.js:131:13) 2015-08-20T07:37:07.490119+00:00 app[web.1]: 在 Route.dispatch (/app/node_modules/express/lib/router/route.js:112:3)

【问题讨论】:

  • 你能解释一下你在哪里得到错误,我的意思是你试图做什么?
  • 您好,请详细描述您的问题。 SO 不是您的错误代码的垃圾场。 (此外,错误会告诉您确切的问题 - 您的应用程序在已发送标头后尝试发送标头 -> 渲染应仅在请求-响应周期中调用一次)
  • @viddesh,在这里我添加了错误日志并改进了我的问题。很抱歉从一开始就没有这样做。我在 ifLoggedIn() 和 ifLoggedOut() 中发现了错误,但我无法完全理解错误背后的原因。
  • @lazlojuly,是的,我认为这就是问题所在。 redirect() 和 next() 会相互影响吗?请检查 IfLoggedIn 函数并帮助我了解问题的原因
  • 我看到你自己解决了这个问题,所以我改进了你的答案,而不是自己回答这个问题。

标签: node.js express connect-flash


【解决方案1】:

此问题出现在 ifLoggedInifLoggedOut 函数中,其中调用了 next() 回调,随后 redirect() 进行了两次后续渲染调用。通过使用returnnext() 回调可以避免这些错误。

原代码:

function ifLoggedOut(req, res, next){
    if(req.isAuthenticated()){
        res.redirect('/list');
    }
    return next();
}

固定版本:

    function ifLoggedOut(req, res, next){
        if(req.isAuthenticated()){
            return res.redirect('/list');
        } 
        return next();
    }

或者if else 可以正确使用(不需要return):

if(req.isAuthenticated()){
    res.redirect('/list');
} else {
    next();
}

不过,使用return 是避免此类错误的好习惯。

【讨论】:

    猜你喜欢
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多