书架/护照:发送后无法设置标题



我在路由的控制台中遇到了一些错误。快速路线如下:

router.get('/getInfo/:id', function(req, res, next) {
  return passport.authenticate('jwt', {session: false}, function(err, account, info) {
   if (err) { return next(err);}
   if (!account) { 
    new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){ 
        return res.status(200).send(acc.toJSON());
    }); 
   }
   if(account._id != req.params.id) { 
    new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){ 
        return res.status(200).send(acc.toJSON());
    });
   }
   else { 
    new Account({_id: req.params.id}).fetch().then(function(acc){ 
        return res.status(200).send(acc.toJSON());
    });
   }
  })(req, res, next);
});

错误消息仅在我未通过身份验证时出现 - 它说

Unhandled rejection Error: Can't set headers after they are sent.
...
at null.<anonymous> (/-----/routes/users.js:61:27)

第 61 行是块中的 res.status(200(..,其中 (account._id != req.params.id(。

代码背后的想法是,如果您请求有关不是您的用户的信息(由 jwt 验证(,您只会获得一些信息 - 现在只有"first_name"。如果您请求有关您自己的信息,则会看到所有信息。

最让我烦恼的是,每次调用路由时,我仍然会得到有效的响应。服务器不会崩溃/拒绝加载/..- 我得到了我所期望的。

我认为它来自对承诺的不当使用

问题是当你写这个

if (!account) { 
    new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){ 
        return res.status(200).send(acc.toJSON());
    }); 
   }

您实际上并没有从函数返回,而是创建一个新帐户并获得承诺的res.status(200)...执行,但随后您继续执行下一行if ... else ...保证您也获得另一个res.status(200)...

的承诺因此,

您确实正在尝试设置两次标题,因此出现错误。

要解决此问题,您有几种解决方案

(1( 在 ifs 中的所有行中添加 ˋreturn'

router.get('/getInfo/:id', function(req, res, next) {
  return passport.authenticate('jwt', {session: false}, function(err, account, info) {
    if (err) { return next(err);}
    if (!account) { 
      return new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){ 
        return res.status(200).send(acc.toJSON());
      }); 
    }
    if(account._id != req.params.id) { 
      return new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){ 
        return res.status(200).send(acc.toJSON());
      });
    }
    else { 
      return new Account({_id: req.params.id}).fetch().then(function(acc){ 
        return res.status(200).send(acc.toJSON());
      });
    }
  })(req, res, next);
});

(2( 链接 ifs,以确保每次调用只执行一次

router.get('/getInfo/:id', function(req, res, next) {
  return passport.authenticate('jwt', {session: false}, function(err, account, info) {
    if (err) { return next(err);}
    if (!account) { 
      new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){ 
        return res.status(200).send(acc.toJSON());
      }); 
    } else if(account._id != req.params.id) { 
      new Account({_id: req.params.id}).fetch({columns: ['first_name']}).then(function(acc){ 
        return res.status(200).send(acc.toJSON());
      });
    } else { 
      new Account({_id: req.params.id}).fetch().then(function(acc){ 
        return res.status(200).send(acc.toJSON());
      });
    }
  })(req, res, next);
});

(3(或者你稍微重组一下你的代码,使其更符合承诺的意图。实际上,您有3种不同的方法来创建帐户,但只有一种方法可以结束通话。我会更明确地说明这一点。那会给出类似的东西

router.get('/getInfo/:id', function(req, res, next) {
  return passport.authenticate('jwt', {session: false}, function(err, account, info) {
    if (err) { return next(err);}
    let createAccountPromise;
    if (!account) { 
      createAccountPromise = new Account({_id: req.params.id}).fetch({columns: ['first_name']});
    } else if(account._id != req.params.id) { 
      createAccountPromise = new Account({_id: req.params.id}).fetch({columns: ['first_name']});
    } else { 
      createAccountPromise = new Account({_id: req.params.id}).fetch();
    }
    return createAccountPromise
      .then(function(acc){ 
        return res.status(200).send(acc.toJSON());
      }); 
  })(req, res, next);
});

相关内容

  • 没有找到相关文章

最新更新