簡體   English   中英

發送標頭后無法設置錯誤

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

這部分代碼導致了我的應用程序出現問題。

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

如果我刪除了第一塊,一切都會正常。 但是第一部分必須存在,才能充當auth中間件。 但它崩潰了,並且出現以下錯誤:

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

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

嘗試在執行redirect()之后立即返回,以避免進一步執行路由處理程序,這也可能會嘗試設置標頭。 您還需要在重定向之前檢查req.url 例如:

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();
});

如果您正在重定向請求,則這將阻止繼續執行( redirect()發送(適當的)標頭)。

您提供的代碼有兩個弱點:

  1. redirect()請求,然后繼續處理它,好像什么都沒發生。 如@mscdex正確指出的那樣,它應該停止處理請求,換句話說,不要在重定向后調用next()
  2. 它的用戶總是重定向到/login ,如果頁面user沒有提供。 即使用戶正在請求/login ,也會創建無數次重定向周期: /login -> [no user] -> [redirect /login] -> /login -> [no user] -> ...

處理用戶授權的最常見模式是:

// 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