如何在NestJS中实现从AWS S3存储桶下载文件
NestJS 从AWS S3直接拉取文件返回下载的实现方案
核心修改逻辑:AWS S3 SDK的
getObject方法支持直接返回可读流,和你原代码用到的createReadStream返回的本地文件流类型完全兼容,直接替换即可完成S3直拉下载,不需要先把文件下载到本地再返回。
修正参数错误后的完整可运行代码如下:
import * as AWS from 'aws-sdk'; import { Response } from 'express'; // 生产环境建议将密钥、桶名等配置放到环境变量中通过NestJS ConfigService获取,不要硬编码 AWS.config.update({ accessKeyId: 'my_access_key', secretAccessKey: 'my_key' }); const s3 = new AWS.S3(); async function downloadFromS3(res: Response) { const options = { Bucket: 'bucket_name', Key: 'key' // 注意首字母必须大写,原代码小写key是无效参数,会导致无法定位S3对象 }; // 设置下载响应头 res.setHeader('Content-disposition', 'attachment; filename=abc.mp3'); // 直接从S3拉取可读流,不需要读取本地文件 const fileStream = s3.getObject(options).createReadStream(); // 可选:添加异常监听处理常见错误场景 fileStream.on('error', (err) => { if (err.code === 'NoSuchKey') { res.status(404).send('请求的文件不存在'); } else if (err.code === 'AccessDenied') { res.status(403).send('无权限访问S3资源,请检查密钥和桶策略配置'); } else { res.status(500).send('文件下载失败'); } }); // 流直接对接响应对象返回给前端 fileStream.pipe(res); }
注意事项
- 如果下载的文件类型不固定,可以先调用
s3.headObject方法获取文件的ContentType、ContentLength等元信息,动态设置响应头,不需要硬编码文件格式 - 如果S3存储桶开启了版本控制,还可以在options中添加
VersionId参数下载指定版本的文件 - 若你的服务和S3桶在同一AWS可用区,建议使用VPC内网端点访问S3,既可以提升速度也能避免公网流量费用
内容的提问来源于stack exchange,提问作者ShrJoshi
相关产品推荐
相关产品推荐

