Express.js错误:发送后无法设置标头

时间:2015-05-28 07:21:41

标签: node.js express

我最近一直收到这个错误,虽然我一直在调查为什么我会收到它但我完全被难过了。我从之前的研究中得知,这个错误通常与后续的res.send()调用有关,其中第二个调用rescend()执行后第二个尝试设置头。

这个过程是一系列的承诺,基本上是从数据库中获取一个对象,处理它,每个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);
                }

            });

        }

关于可能发生的事情的任何想法?是否有可能由于请求的数量而导致某些承诺在以后执行并且在响应已经发送后尝试发送?

1 个答案:

答案 0 :(得分:0)

承诺将像这样工作 我将在nodejs中使用Q npm lib解释一些小例子 validate.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);
                    }



                });

            }).