Nodejs重定向 - 错误:发送后无法设置标头

时间:2017-07-24 05:08:41

标签: node.js express firebase firebase-authentication

引用此问题尚无答案=> QUESTION

在快速nodejs中验证令牌后,我无法重定向。

app.post('/server', function(req,res, next){
    var idToken = '';
    req.on('data', function (chunk) {
        var obj = JSON.parse(chunk);
        idToken = obj.idToken;
       firebase.auth().verifyIdToken(idToken)
          .then(function(decodedToken) {
           var uid = decodedToken.uid;
           authenticationFlag = true;
           res.redirect('/profile');
         }).catch(function(error) {
            console.log('ERROR IS:'+error);
            authenticationFlag = false;
       });
  });
  res.end('');
});

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

基本上我想在用户登录后将用户重定向到个人资料。

4 个答案:

答案 0 :(得分:0)

您在解析promise之前调用res.end()(因为这是异步代码)。 res.end结束响应过程。

当您尝试在promise范围内调用res.redirect时,该对象已经关闭。

当promise已经解决时,尝试在promise中移动res.end()。

app.post('/server', function(req,res, next){
    var idToken = '';
    req.on('data', function (chunk) {
        var obj = JSON.parse(chunk);
        idToken = obj.idToken;
        firebase.auth().verifyIdToken(idToken)
          .then(function(decodedToken) {
           var uid = decodedToken.uid;
           authenticationFlag = true;
           res.redirect('/profile');
           res.end();
         }).catch(function(error) {
            console.log('ERROR IS:'+error);
            authenticationFlag = false;
            res.status(ERROR_CODE).end();
       });  
    });
});

答案 1 :(得分:0)

您的问题出在最后一行res.end('')的第二行,这是在调用异步函数firebase.auth()之前调用的。

在文档http://expressjs.com/en/api.html中,res.end函数用于快速返回没有数据的响应,有点像空回报

  

用于在没有任何数据的情况下快速结束响应

所以你的逻辑如下:

console.log('start');

Promise.resolve('firebase results, after res.end is called!')
       .then(value => console.log(value))
       
console.log('This is ran before the Promise! Where the res.end is');

因此,在firebase的承诺可以返回之前,您的代码会“退出”。您的解决方案是删除res.end()并添加一些错误处理逻辑。

e.g。在你的问题的背景下:

    app.post('/server', function(req,res, next){
    var idToken = '';
    req.on('data', function (chunk) {
        var obj = JSON.parse(chunk);
        idToken = obj.idToken;
       firebase.auth().verifyIdToken(idToken)
          .then(function(decodedToken) {
           var uid = decodedToken.uid;
           authenticationFlag = true;
           res.redirect('/profile');
         }).catch(function(error) {
            console.log('ERROR IS:'+error);
            authenticationFlag = false;
            res.status(400).send('Wrong details');
       });
  });
});

答案 2 :(得分:0)

这两个答案对我都不起作用(可能它们适合你)。所以我做了别的事。在我的客户端文件中,令牌被发送到服务器

我已将其重定向到那里。

       $.ajax({
            url: 'http://localhost:9615/server',

            data: '{"idToken": "'+idToken+'"}',
            type: 'POST',
            jsonpCallback: 'callback', // this is not relevant to the POST anymore
            success: function (data) {
               window.location = "profile";
            },
            error: function (xhr, status, error) {
                console.log('Error: ' + error.message);
            },
        });

有效。

答案 3 :(得分:0)

当我所在的特定函数中有更多代码时,res.redirect出现了同样的错误。

重定向后,return false解决了我的问题。

例如,

res.redirect('/profile'); return false;