【问题标题】:Express.js Error: Can't set headers after they are sentExpress.js 错误:发送后无法设置标头
【发布时间】:2015-08-10 13:29:02
【问题描述】:

我最近经常收到这个错误,虽然我一直在调查为什么我可能会收到这个错误,但我完全被难住了。我从以前的研究中知道,此错误通常与随后的 res.send() 调用相关联,其中第二个调用在 res.end() 执行后尝试设置标头。

这个过程是一系列的promise,基本上从从数据库中获取一个对象开始,处理它,每个promise使用前一个promise的结果从数据库中获取其他东西并处理它,直到我们最终构建一个对象,然后发回给用户。

另一件事是我们每秒收到超过 2000 个请求,过了一段时间我开始在日志中看到错误。完整的错误信息是这样的,然后是一堆 Express Timeout 错误:

Can't set headers after they are sent.
Error: Can't set headers after they are sent.
   at ServerResponse.OutgoingMessage.setHeader (http.js:689:11)
   at ServerResponse.res.setHeader (/express/node_modules/connect/lib/patch.js:59:22)
   at ServerResponse.res.set.res.header (/node_modules/express/lib/response.js:522:10)
   at ServerResponse.res.jsonp (/node_modules/express/lib/response.js:236:8)
   at validator.validate.then.then.then.then.then.then.then.then.then.fail.res.send.code (<path-to-module>/module.js:131:29)
   at _fulfilled (/node_modules/q/q.js:798:54)
   at self.promiseDispatch.done (/node_modules/q/q.js:827:30)
   at Promise.promise.promiseDispatch (/node_modules/q/q.js:760:13)
   at /node_modules/q/q.js:574:44
   at flush (/node_modules/q/q.js:108:17)

这里是代码:

           app.get('/endpoint', function (req, res) {

            validator.validate(req.query, {
                // check query to see if valid

            }).then(function (valResult) {
               // if result passes validation get application id from database

            }).then(function (app) {
            // do a bunch of IO operations to build resulting object
            }).then
            }).then
            }).then
            }).then(function (result) {

                // This is where I am getting the error

                if (result.platform === 'mobile') {
                    res.jsonp({code: 100, message: 'SUCCESS', data: result});
                }
                else {
                    res.send({code: 100, message: 'SUCCESS', data: result});
                }

            }).fail(function (error) {

                if (error.stack) {
                    console.log(error.message);
                    console.log(error.stack);
                    res.send({code: 500, message: 'FAIL_SYSTEM', data: error.message});
                } else {
                    res.send(error);
                }

            });

        }

对可能发生的事情有任何想法吗?是否有可能由于请求的数量,某些承诺稍后执行并在响应已经发送后尝试发送?

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    promises 会像这样工作 他我将解释在 nodejs 中使用 Q npm lib 的小例子 验证.js

    var q = require('q');
    function validate (query)
    {
    var deferred = q.difere();
    ------validation logic -----
    if (validation success)
    {
    deferred.resolve(validationResult);
    }
    else
    {
    deferred.reject(validationResult);
    }
    return deferred;
    }
    

    在控制器中你可以写承诺

      var validator = require('./validator.js');
         app.get('/endpoint', function (req, res) {
    
                    validator.validate(req.query)
                    .then(function (valResult) {
    
                        //same db query 
    
                         Model.find({},function(error, result){
    
                         if(!error)
                          {
                          return result ;
                          }
                          });
    
                         }
    
                        ).then(function (result) {
    
                        // This is where I am getting the error
    
                        if (result.platform === 'mobile') {
                            res.jsonp({code: 100, message: 'SUCCESS', data: result});
                        }
                        else {
                            res.send({code: 100, message: 'SUCCESS', data: result});
                        }
    
                    }).fail(function (error) {
    
                        if (error.stack) {
                            console.log(error.message);
                            console.log(error.stack);
                            res.send({code: 500, message: 'FAIL_SYSTEM', data: error.message});
                        } else {
                            res.send(error);
                        }
    
    
    
                    });
    
                }).
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-01
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      • 1970-01-01
      • 2014-02-13
      • 2018-06-08
      相关资源
      最近更新 更多