【问题标题】:Download file in Express route, serve to the client, then remove在 Express 路由中下载文件,提供给客户端,然后删除
【发布时间】:2021-02-20 06:11:57
【问题描述】:

我有一个生成文件的内部 HTTP Post API,每个文件大小为 5-10mb。此服务不可修改。
我想通过基于 Node.js+Express 的公共 API 来“代理”这个文件下载。但是,我想不出最好的方法。

我想我可以使用 Axios 将此文件下载到 Node.js API 容器中的临时文件中,但这似乎很容易出现这些临时文件可能堆积并需要稍后清理的问题。有没有办法实现这样的文件下载-> 在不创建临时文件的情况下进一步发送给客户端? 或者如果临时文件是不可避免的,那么最有效和“干净”的方法是什么?

router.post('/route/:someid',
    [someRequestVerificationMiddleware],
    (req, res, next) => {
      const myFileId = req.params.someid;

      const downloadRequestParams= {
        "id": myFileId 
      };
      let dlPromise = axios.post(`http://myinternalservice:80`,
          downloadRequestParams, {responseType: "stream"});
      dlPromise.then(response => {
        try {
          let filename = response.headers["x-result-filename"];

          //
          // What would be the most efficient way to return the received file
          // from response data to the client calling this route without creating
          // too much garbage?
          //
          

        } catch (e) {
          console.error(e);
        }
      })
          .catch(e=>{
            console.error(e);
          res.status(500);
      })
          .finally(() => {
            next();
      })
    });

module.exports = router;

【问题讨论】:

  • 仅供参考,您不会在发送响应的请求处理程序中调用next()。当您希望路由继续到其他路由处理程序时,您仅在中间件中调用 next() - 其中一个将发送响应。

标签: node.js express axios


【解决方案1】:

res 是一个流。您可以简单地将您的 axios 流通过管道传递给响应。

    res.setHeader("content-type", "...");
    return dlPromise.then((response) => response.data.pipe(res));

【讨论】:

  • 谢谢!这样可行。为了将来参考,我还添加了res.setHeader("content-disposition", "attachment; filename=" + filename);,用于建议重定向文件下载的名称。所以它不仅仅是response
猜你喜欢
  • 2012-07-23
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
相关资源
最近更新 更多