发送错误后无法设置标头

时间:2016-01-17 09:40:30

标签: javascript node.js express

这段代码导致我的应用程序出现问题。

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

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

如果我删除了第一个块,一切正常。但第一部分必须在那里,作为auth中间件。但它崩溃了,我得到了以下错误:

$client = \Eway\Rapid::createClient($apiKey, $apiPassword, $apiEndpoint);       
$response = $client->queryTransaction(166593832);
print_r($response);

//result
Eway\Rapid\Model\Response\QueryTransactionResponse Object ( [fillable:protected] => Array ( [0] => Transactions [1] => Errors [2] => Message ) [errors:protected] => Array ( ) [attributes:protected] => Array ( [Transactions] => Array ( ) [Errors] => ) )

2 个答案:

答案 0 :(得分:0)

在执行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 :(得分:0)

您提供的代码中有两个弱点:

  1. 请求redirect()然后继续处理它,好像什么都没发生一样。它应该停止处理请求,换句话说,在重定向后不调用next(),正如@mscdex正确指出的那样。
  2. 如果未提供/login,它始终会将用户重定向到user页面。即使用户请求/login,也会创建无限循环的重定向:/login -> [no user] -> [redirect /login] -> /login -> [no user] -> ...
  3. 处理用户授权的最常见模式是:

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