Node.js 错误:";Can';t在发送标题后设置标题。”;

Node.js 错误:";Can';t在发送标题后设置标题。”;,node.js,express,connect-flash,Node.js,Express,Connect Flash,我对nodejs及其路由系统不熟悉。我得到的是“发送后无法设置标题”。仅在生产模式下,仅在Heroku上(在本地可以正常工作) //登录========================================= router.get('/', ifLoggedOut, function(req, res, next){ res.render('login', { message: req.flash('message')}); }); router.post('/login',

我对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);
}
//功能================================================

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应用程序[web.1]:错误:发送标题后无法设置标题。 2015-08-20T07:37:07.490096+00:00应用程序[web.1]:位于ServerResponse.OutgoingMessage.setHeader(_http_outgoing.js:335:11) 2015-08-20T07:37:07.490098+00:00应用程序[web.1]:位于ServerResponse.header(/app/node\u modules/express/lib/response.js:718:10) 2015-08-20T07:37:07.490099+00:00应用程序[web.1]:在ServerResponse.send(/app/node\u modules/express/lib/response.js:163:12) 2015-08-20T07:37:07.490101+00:00应用程序[web.1]:完成时(/app/node_modules/express/lib/response.js:957:10) 2015-08-20T07:37:07.490103+00:00应用程序[web.1]:at View.exports.renderFile[作为引擎](/app/node_modules/ejs/lib/ejs.js:355:10) 2015-08-20T07:37:07.490105+00:00应用程序[web.1]:在View.render(/app/node_modules/express/lib/View.js:126:8) 2015-08-20T07:37:07.490106+00:00应用程序[web.1]:在tryRender(/app/node_modules/express/lib/application.js:639:10) 2015-08-20T07:37:07.490108+00:00应用程序[web.1]:在EventEmitter.render(/app/node_modules/express/lib/application.js:591:3) 2015-08-20T07:37:07.490109+00:00应用程序[web.1]:位于ServerResponse.render(/app/node_modules/express/lib/response.js:961:7) 2015-08-20T07:37:07.490111+00:00应用程序[网站1]:at/app/routes/routes.js:7:7 2015-08-20T07:37:07.490112+00:00APP[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应用程序[网站1]:在ifLoggedOut(/app/routes/routes.js:181:10) 2015-08-20T07:37:07.490117+00:00应用程序[web.1]:在Layer.handle[作为handle\u请求](/app/node\u 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]:at Route.dispatch(/app/node\u modules/express/lib/router/Route.js:112:3)


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

原始代码:

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
):


不过,使用
return
是避免此类错误的良好实践

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