Nodejs 发送部分响应
Posted
技术标签:
【中文标题】Nodejs 发送部分响应【英文标题】:Nodejs send partial response 【发布时间】:2015-09-29 03:17:13 【问题描述】:mongodb 集合中有 20,000 条记录。我将所有这些记录导出到 csv 中。我使用这个发送部分响应:
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();
);
;
【问题讨论】:
你能展示你的完整代码吗?问题不在于你放在这里的东西。理想情况下足以运行并查看问题(模拟数据可能是个好主意)。 您在批处理操作完成之前发回响应。 问题现已解决。 ***.com/questions/31339652/… 显然,您在写入标头之前发送了数据。不管怎样,为什么不把你的答案标记为更正呢? 【参考方案1】:为什么不直接流式传输数据?您可以使用猫鼬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
);
【讨论】:
【参考方案2】:此声明
res.writeHead(200,
"Content-Type": "application/csv",
"Content-disposition": "attachment; filename='import.csv'"
);
当您发送响应时属于标题部分。因此,它发送标题。 res.end() 也发送header。所以,这样你再次发送header。
请参考这个stackoverlflow问题 编辑代码:
data.pipe(resp);
resp.end();
更多请参考这个pipe
【讨论】:
即使这个条件没有被执行,我也得到了错误。【参考方案3】: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();
);
;
【讨论】:
提交答案时,请在您的代码中添加一些解释。 是 write 立即发送数据,作为部分响应,还是将数据写入缓冲区,等待发送?以上是关于Nodejs 发送部分响应的主要内容,如果未能解决你的问题,请参考以下文章
当内容类型为“text/xml”时,Axis2 发送多部分响应