You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS使用@aws-sdk/client-s3 v3如何将S3文件通过API返回供下载

你之前调用pipe失败的核心原因是awsCtrl.getObject返回的是完整的S3响应对象,可读流实际存储在该对象的Body属性中,你直接对整个响应对象调用pipe当然不会生效。

下面是修改后的可正常运行的代码,全程采用流传输,不会将文件写入服务端本地磁盘,完全符合你的需求:

const { Readable } = require('stream'); // 低版本SDK需要用到,版本较新可省略

filesCtrl.deliverFile = async (req, res) => {
  // 补充获取实际S3文件路径和下载文件名的逻辑,以下为示例
  const filePath = req.params.fileId;
  const filename = "自定义下载文件名";
  const result = {};

  /* Get object from AWS S3 */
  let s3Response;
  try {
    s3Response = await awsCtrl.getObject(filePath);
  } catch (e) {
    consoleLogger.error(`Unable to get object from AWS S3`, e);
    if (e.status && e.status === 404) {
      result.error = `Not found`;
      return res.status(404).json(result);
    }
    return res.status(e.status || 500).json(result);
  }

  // 设置下载响应头
  res.attachment(filename);
  // 复用S3返回的文件类型,避免客户端识别错误
  res.setHeader('Content-Type', s3Response.ContentType || 'application/octet-stream');
  // 可选配置Content-Length,方便客户端显示下载进度
  if (s3Response.ContentLength) {
    res.setHeader('Content-Length', s3Response.ContentLength);
  }

  // 提取S3返回的文件流
  let fileStream = s3Response.Body;
  // 低版本SDK返回Web Stream的话,用以下代码转成Node.js可读流,版本较新可省略
  // fileStream = Readable.fromWeb(fileStream);

  // 流传输到客户端
  fileStream.pipe(res);

  // 监听流传输错误,避免服务崩溃
  fileStream.on('error', (err) => {
    consoleLogger.error('File stream error:', err);
    if (!res.headersSent) {
      res.status(500).json({ error: 'File download failed' });
    }
  });
}

注意事项

  • 如果你的@aws-sdk/client-s3版本≥3.180.0,Node环境下默认返回的Body就是Node.js可读流,不需要额外做格式转换
  • 传输过程中服务端仅做流转发,不会缓存完整文件,资源占用极低

内容的提问来源于stack exchange,提问作者pengz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:45:01