Nodejs发送部分响应

时间:2015-07-10 11:29:03

标签: node.js csv export-to-csv

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();

        }

    });
}
};

3 个答案:

答案 0 :(得分:2)

为什么不直接传输数据?您可以使用mongoose 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 :(得分:1)

本声明

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

属于标题部分。因此,它发送标题。
res.end()也会发送标题。这样,您就可以再次发送标题。

请参阅此stackoverlflow个问题


编辑代码:

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

请参阅此内容以获取更多pipe

答案 2 :(得分: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();
            }

        });
    }
};