【问题标题】:Using Node/Express to stream file to user for download使用 Node/Express 将文件流式传输给用户以供下载
【发布时间】:2017-04-02 21:58:51
【问题描述】:

我想使用 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');
    })
});

这不起作用,因为res.download() 只接受文件的路径。我想从内存中的对象发送响应。现有的 Node/Express API 怎么可能做到这一点?


设置适当的标头也不会触发下载:

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

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    这对我有用。 我使用内容类型 octet-stream 来强制下载。 在 chrome 上测试,json 被下载为“data.json”
    你不能用ajax下载根据:Handle file download from 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);
    

    【讨论】:

    • 看起来您正在阅读 data.json 文件,不过。如何执行相同的行为并发送普通对象{"some": "json"}
    • 您从客户端包含了哪些标头?
    • 我编辑了它使下载序列化 JSON 但不是作为 Stream 的代码。
    • 你是如何从客户端发出请求的?
    • curl 和 chrome 但它也应该与 ajax 一起使用,我要检查一下。
    【解决方案2】:

    可以设置header强制下载,然后使用res.send

    查看这些链接

    【讨论】:

    • 我看到了,您问的问题与我提供的第一个链接中的问题相同
    • 该链接没有为我提供足够的信息来解决我遇到的问题。
    猜你喜欢
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    相关资源
    最近更新 更多