简体   繁体   English

发送标头后无法设置错误

[英]Can\'t set headers after they are sent error

This part of code caused the problem to my app. 这部分代码导致了我的应用程序出现问题。

router.use(function(req, res, next){
  if(req.user){
    res.locals.username = req.user.username
  }else{
    res.redirect('/login');
  }
  next();
});

router.get('/', function(req, res, next) {
    res.render('dashboard');
});

If I removed the first block, everything worked fine. 如果我删除了第一块,一切都会正常。 But the first part have to be there, to act as the auth middleware. 但是第一部分必须存在,才能充当auth中间件。 But it crashed and I got error of below: 但它崩溃了,并且出现以下错误:

_http_outgoing.js:341
    throw new Error('Can\'t set headers after they are sent.');
    ^

Error: Can't set headers after they are sent.

Try returning immediately after performing the redirect() to avoid further route handler executions that may also try to set headers. 尝试在执行redirect()之后立即返回,以避免进一步执行路由处理程序,这也可能会尝试设置标头。 You will also want to check req.url before redirecting. 您还需要在重定向之前检查req.url For example: 例如:

router.use(function(req, res, next){
  if (req.user) {
    res.locals.username = req.user.username
  } else if (!/\/login/i.test(req.url)) {
    return res.redirect('/login');
  }
  next();
});

This will prevent execution from continuing if you are redirecting the request ( redirect() sends (the appropriate) headers). 如果您正在重定向请求,则这将阻止继续执行( redirect()发送(适当的)标头)。

There are 2 weak points in the code you provided: 您提供的代码有两个弱点:

  1. It redirect() the request and then continue processing it as if nothing happened. redirect()请求,然后继续处理它,好像什么都没发生。 It should stop processing the request, in other words not call next() after redirect, as @mscdex correctly pointed out. 如@mscdex正确指出的那样,它应该停止处理请求,换句话说,不要在重定向后调用next()
  2. It always redirects the user to the /login page if the user is not provided. 它的用户总是重定向到/login ,如果页面user没有提供。 Even if the user is requesting /login , creating endless cycles of redirects: /login -> [no user] -> [redirect /login] -> /login -> [no user] -> ... 即使用户正在请求/login ,也会创建无数次重定向周期: /login -> [no user] -> [redirect /login] -> /login -> [no user] -> ...

The most common pattern to handle user authorization is this: 处理用户授权的最常见模式是:

// middleware to check user authorization
function checkAuth(req, res, next){
  if(req.user){
    res.locals.username = req.user.username
    next(); // authorization handled successfully, continue processing request
  }else{
    res.redirect('/login');
    // finish processing request without calling next()
  }
}

// we add checkAuth middleware to prevent unauthorized users from accessing server root ('/')
router.get('/', checkAuth, function(req, res, next) {
    res.render('dashboard');
});
// but we don't need to check user authorization on '/login'
router.get('/login', function(req, res, next) {
    res.render('...');
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM