2015-07-10 166 views
5

mongodb集合中有20,000条记录。我在csv中导出所有这些记录。我用这个发送部分响应:Nodejs发送部分响应

res.writeHead(200, { 
        "Content-Type": "application/csv", 
        "Content-disposition": "attachment; filename='import.csv'" 
}); 

res.write(data + '0', "binary"); 

上面的代码一批500我使用此代码时,所有记录都处理结束时执行。

if (++responseCount == loopCount) { 
    res.end(); 
} 

但我得到这个错误:

不能设置头发送之后。

但我得到的文件下载了500条记录。

这是我的完整代码。

var exportData = function (req, res, next) { 

var limit = 500; 
var responseCount = 0; 
var loopCount = 1; 
var size = 30000; 

//Get 500 records at one time 
var getData = function (req, start, cb) { 
    req.db.collection('items').find().skip(start).limit(limit).toArray(function (err, records) { 
     if (err) throw err; 
     cb(null, records); 
    }); 
}; 

if (size > limit) { 
    loopCount = parseInt(req.size/limit); 

    if ((req.size % limit) != 0) { 
     loopCount += 1; 
    } 
} 

for (var j = 0; j < loopCount; j++) { 

    getData(req, limit * j, function (err, records) { 

     if (err) throw err; 

     records.forEach(function (record) { 
      //Process record one by one 
     }); 

     res.write(records); 

     if (++responseCount == loopCount) { 
      res.setHeader('Content-type', 'application/csv'); 
      res.setHeader("Content-disposition", 'attachment; filename="import.csv"'); 
      res.end(); 

     } 

    }); 
} 
}; 
+0

你能展现完整的代码?问题不在于你放在这里。理想状态下运行并查看问题(嘲笑数据可能是个好主意)。 –

+0

在批量操作完成之前,您正在发回响应。 – bluesman

+0

现在问题已解决。 http://stackoverflow.com/questions/31339652/nodejs-send-partial-response/31398864#31398864 – Rohit

回答

1

本声明

res.writeHead(200, { 
        "Content-Type": "application/csv", 
        "Content-disposition": "attachment; filename='import.csv'" 
}); 

属于当你的反应是send.So到标题部分,将它发送头。
res.end()也发送头。所以,用这种方法你再次发送头。

请参考这个stackoverlflow问题


编辑代码:

data.pipe(resp); 
resp.end(); 

请参考这一个多pipe

+0

即使未执行此条件,我也收到了错误。 – Rohit

2

为什么不只是流中的数据?你可以使用猫鼬query.stream功能。来自文档的示例:

// follows the nodejs 0.8 stream api 
Thing.find({ name: /^hello/ }).stream().pipe(res) 

该流将为您处理数据流。作为Node.js的流,还可以监听事件:

// manual streaming 
var stream = Thing.find({ name: /^hello/ }).stream(); 

stream.on('data', function (doc) { 
    // do something with the mongoose document 
}).on('error', function (err) { 
    // handle the error 
}).on('close', function() { 
    // the stream is closed 
}); 
1
var exportData = function (req, res, next) { 

    res.writeHead(200, { 
     'Content-Type': 'application/csv', 
     'Content-Disposition': 'attachment; filename="import.csv"' 
    }); 

    var limit = 500; 
    var responseCount = 0; 
    var loopCount = 1; 
    var size = 30000; 

    //Get 500 records at one time 
    var getData = function (req, start, cb) { 
     req.db.collection('items').find().skip(start).limit(limit).toArray(function (err, records) { 
      if (err) throw err; 
      cb(null, records); 
     }); 
    }; 

    if (size > limit) { 
     loopCount = parseInt(req.size/limit); 

     if ((req.size % limit) != 0) { 
      loopCount += 1; 
     } 
    } 

    for (var j = 0; j < loopCount; j++) { 

     getData(req, limit * j, function (err, records) { 

      if (err) throw err; 

      records.forEach(function (record) { 
       //Process record one by one 
      }); 

      res.write(records); 

      if (++responseCount == loopCount) { 
       res.end(); 
      } 

     }); 
    } 
}; 
+1

提交答案时,请向您的代码添加一些说明。 – MayorMonty

+0

确实。一些代码解释应该是有序的。 – MoshMage

+0

将写入作为部分响应立即发送数据,还是将数据写入缓冲区,等待发送? – 2017-06-05 13:44:23