如何将文件附件流式传输到node.js中的响应?

时间:2017-06-05 17:08:20

标签: javascript node.js express

使用node.js / Express.js,我想调用API,将该调用的响应写入文件,然后将该文件作为客户端的附件提供。 API调用返回正确的数据,并且数据已成功写入文件;问题是,当我尝试将该文件从磁盘流式传输到客户端时,获取服务的文件附件为空。这是我的路由处理程序的主体:

// Make a request to an API, then pipe the response to a file. (This works)
request({
  url: 'http://localhost:5000/execute_least_squares',
  qs: query
}).pipe(fs.createWriteStream('./tmp/predictions/prediction_1.csv', 
  {defaultEncoding: 'utf8'}));

// Add some headers so the client know to serve file as attachment  
res.writeHead(200, {
    "Content-Type": "text/csv",
    "Content-Disposition" : "attachment; filename=" + 
    "prediction_1.csv"
});

// read from that file and pipe it to the response (doesn't work)
fs.createReadStream('./tmp/predictions/prediction_1.csv').pipe(res);

问题:

为什么响应只是将空白文档返回给客户端?

考虑:

C1。这个问题是否发生,因为当最后一行尝试读取文件时,编写它的过程还没有开始?

C1.a)不知道createWriteStream和createReadStream都是异步的,确保createWriteStream会在事件循环中的createReadStream之前吗?

C2。可能是数据'事件没有被正确触发?不管你抽象抽出这个吗?

感谢您的意见。

1 个答案:

答案 0 :(得分:3)

试试这个:

var writableStream = fs.createWriteStream('./tmp/predictions/prediction_1.csv',
{ defaultEncoding: 'utf8' })

request({
    url: 'http://localhost:5000/execute_least_squares',
     qs: query
}).pipe(writableStream);

//event that gets called when the writing is complete
writableStream.on('finish',() => {
    res.writeHead(200, {
    "Content-Type": "text/csv",
    "Content-Disposition" : "attachment; filename=" + 
    "prediction_1.csv"
});
    var readbleStream = fs.createReadStream('./tmp/predictions/prediction_1.csv')
   readableStream.pipe(res);
}

您应捕获两个流(写入和读取)的on。(' error'),以便您可以返回合适的响应(400或其他)。

欲了解更多信息:

Read the Node.js Stream documentation

注意事项:

  

这个问题是否发生,因为当最后一行尝试读取文件时,编写它的过程还没有开始?

答:是的。或者另一种可能性是请求尚未完成。

  

不知道createWriteStream和createReadStream都是异步的,确保createWriteStream会在事件循环中的createReadStream之前吗?

答:根据我在docs中读到的内容,createWriteStream和createReadStream是同步的,它们只返回一个WriteStream / ReadStream对象。

  

可能是'数据'事件没有被正确触发?不管你抽象抽出这个吗?

答:如果你在谈论这段代码:

request({
    url: 'http://localhost:5000/execute_least_squares',
    qs: query
}).pipe(fs.createWriteStream('./tmp/predictions/prediction_1.csv', 
   {defaultEncoding: 'utf8'}));

它根据请求文档工作。如果您正在谈论其他内容,请更详细地解释。