不断收到错误:发送后无法设置标头

Posted

技术标签:

【中文标题】不断收到错误:发送后无法设置标头【英文标题】:Keep getting Error: Can't set headers after they are sent 【发布时间】:2017-10-17 15:25:49 【问题描述】:

所以我正在尝试更新我的代码并将其展示给用户。基本上它能够做我需要做的事情,但是在执行之后我得到了这个错误

C:\Users\tester01_2\myproject\node_modules\mongodb-core\lib\cursor.js:174 抛出错误; ^ 错误:发送后无法设置标头。 在 ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11) 在 ServerResponse.header ( C:\Users\tester01_2\myproject\node_modules\express\lib\response.js:725:10) 在 ServerResponse.send (C:\Users\tester01_2\myproject\node_modules\express\lib\response.js:170:12) 在 C:\Users\tester01_2\myproject\dbUpdate.js:13:14 在 C:\Users\tester01_2\myproject\dbUpdate.js:28:5 在 handleCallback (C:\Users\tester01_2\myproject\node_modules\mongodb- 核心\lib\cursor.js:171:5) 在 nextFunction (C:\Users\tester01_2\myproject\node_modules\mongodb- 核心\lib\cursor.js:682:5) 在 Cursor.next [as _next] (C:\Users\tester01_2\myproject\node_modules\mongodb- 核心\lib\cursor.js:692:3) 在循环 (C:\Users\tester01_2\myproject\node_modules\mongodb\lib\cursor.js:694:8) 在每一个 (C:\Users\tester01_2\myproject\node_modules\mongodb\lib\cursor.js:741:16)

这是我的代码

var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/myproject';

module.exports = 

postCollection : function(req, res)
    var issueQty = req.body.issueQty;
    var itemDescrip = req.body.itemDescrip;
MongoClient.connect(url, function(err, db) 
    assert.equal(null, err);
    updateRecord(db, req, function(doc) 
    return res.send('Record Found. Now updating this document...' + 
itemDescrip + ' Record Updated. This is the new record ' + doc )
    res.end();
    db.close();
    );

);


var updateRecord = function(db, req, callback) 
var cursor = db.collection('documents').find('Item Description': 
req.body.itemDescrip, 'Issued QTY': req.body.issueQty)
cursor.each(function(err,doc)
   assert.equal(err, null);
     if(doc != err)
         console.log('Successfully queried');
         console.log(doc);
         callback(JSON.stringify(doc));

      else
         throw err;
     
  );
db.collection('documents').updateMany(
   'Item Description': req.body.itemDescrip,
  
    $set:  'Issued QTY': req.body.issueQty 
  ,function(err, results) 
    console.log(results);
    console.log('Done');
    console.log(results);

);
;

我认为这与我的 res 有关,因为我看到的所有线程都处于错误位置,但我需要将我的 res.send 放在那里,以便它可以使用 doc。有没有办法解决这个问题?谢谢。

【问题讨论】:

【参考方案1】:

首先,你应该删除res.send()前面的return

其次,在updateRecord函数中,callback函数不应该循环调用,它会执行多次。在执行updateMany 之前关闭数据库。

如果你想发送 doc,你应该使用一个临时数组来保存 doc,并在你完成 updateRecord 中的所有逻辑时将它传递给 res。

如果我理解正确,以下是我对您的代码的修改,

var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/myproject';

var updateRecord = function(db, req, callback) 
    db.collection('documents').updateMany( 'Item Description': req.body.itemDescrip , 
        $set:  'Issued QTY': req.body.issueQty 
    , function(err, results) 
        if (err) return callback(err);
        console.log('Done');
        console.log(results);
        var cursor = db.collection('documents').find(
            'Item Description': req.body.itemDescrip,
            'Issued QTY': req.body.issueQty
        );
        var temp = [];
        cursor.each(function(err, doc) 
            if (err) 
                return callback(err);
            
            console.log('Successfully queried');
            console.log(doc);
            temp.push(JSON.stringify(doc));
        );
        callback(null, temp);
    );
;

module.exports = 
    postCollection: function(req, res) 
        var issueQty = req.body.issueQty;
        var itemDescrip = req.body.itemDescrip;
        MongoClient.connect(url, function(err, db) 
            if(err) 
              res.send(err);
              res.end();
              db.close();
              return;
            
            updateRecord(db, req, function(err, docs) 
                if(err)
                  res.send(err);
                
                else
                  res.send(docs);
                
                res.end();
                db.close();
            );

        );
    

【讨论】:

@OngKongTat 我更新了我的答案,你应该检查你的 updateRecord 函数两次。 对不起,我真的不明白你所说的循环是什么意思,你是指函数还是 for/while 循环等?你怎么知道什么时候放 db.close() 因为我有点困惑。 @OngKongTat cursor.each 是一个循环,你的回调函数是在updateMany之前调用的,所以你在调用updateMany之前调用db.close。 我无法将带有 doc 的临时数组传递给 res,因为 doc 将是未定义的,因为 doc 是在另一个函数中声明的函数中,所以我不完全知道我应该如何调整功能,以便 doc 能够在 postCollection 中使用。 @OngKongTat 我更新了我的答案,你看看我是否理解正确。

以上是关于不断收到错误:发送后无法设置标头的主要内容,如果未能解决你的问题,请参考以下文章

使用 Node/Express 不断收到“发送后无法设置标题”

为啥我在 Nodejs 中收到“无法在将标头发送到客户端后设置标头”错误?

错误:在我初始化会话后发送标头后无法设置标头

错误:发送后无法设置标头。

异步发送错误后无法设置标头

为啥显示此错误?发送到客户端后无法设置标头