使用 Node/Express 将文件流式传输给用户下载

Him*_*mel 1 node.js express

我想使用 Node/Express 服务器将文件作为附件流式传输到客户端。我想从客户端向端点发出异步请求/download,然后将通过 API 代理接收到的对象作为可下载文件提供给客户端(类似于res.attachment(filename); res.send(body);行为方式)。

例如:

fetch(new Request('/download'))
    .then(() => console.log('download complete'))

app.get('/download', (req, res, next) => {
    // Request to external API
    request(config, (error, response, body) => {
        const jsonToSend = JSON.parse(body);
        res.download(jsonToSend, 'filename.json');
    })
});
Run Code Online (Sandbox Code Playgroud)

这将不起作用,因为res.download()只接受文件的路径。我想发送内存中对象的响应。现有的 Node/Express API 如何实现这一点?


设置适当的标头不会触发下载,或者:

    res.setHeader('Content-disposition', 'attachment; filename=filename.json');
    res.setHeader('Content-type', 'application/json');
    res.send({some: 'json'});
Run Code Online (Sandbox Code Playgroud)

小智 5

这对我有用。我使用内容类型八位字节流来强制下载。在 chrome 上测试,json 被下载为“data.json”,
您无法根据以下内容使用 ajax 进行下载: 处理从 ajax post 下载的文件

您可以使用 href/window.location/location.assign。该浏览器将检测 mime 类型application/octet-stream,并且不会更改实际页面,只会触发下载,以便您可以将其包装为 ajax 成功调用。

//client
const endpoint = '/download';

fetch(endpoint, {
  method: 'POST',
  credentials: 'include',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  }
  })
  .then(res => res.json())
  .then(res => {
     //look like the json is good to download
     location.assign(endpoint);
   })
   .catch(e => {
     //json is invalid and other e
   });

//server
const http = require('http');

http.createServer(function (req, res) {
    const json = JSON.stringify({
      test: 'test'
    });
    const buf = Buffer.from(json);
    res.writeHead(200, {
      'Content-Type': 'application/octet-stream',
      'Content-disposition': 'attachment; filename=data.json'
    });
    res.write(buf);
    res.end();
}).listen(8888);
Run Code Online (Sandbox Code Playgroud)