如何使用AWS SDK v3将流上传到S3并解决501 Not Implemented错误
问题原因
你遇到的501错误是因为AWS SDK v3的PutObjectCommand/putObject接口和v2的s3.upload底层逻辑不同:
- v2的
s3.upload默认使用S3分块上传API,自动适配未知长度的流,不需要提前获取文件总大小,不会触发分块传输编码 - v3的
PutObject系列接口仅支持单块上传,要求请求必须携带Content-Length头,当传入未知长度的流时,SDK会自动添加Transfer-Encoding: chunked头,但S3原生不支持该编码格式,因此直接返回501 Not Implemented错误。
解决方案
AWS SDK v3专门提供了对标v2s3.upload的工具类Upload,位于@aws-sdk/lib-storage包中,体积轻量,完全满足你内存流上传、不写磁盘的需求。
步骤1:安装依赖
npm install @aws-sdk/client-s3 @aws-sdk/lib-storage
步骤2:替换上传函数
你原有请求流复制、PassThrough流的逻辑完全不需要修改,只需要调整uploadToFirstS3/uploadToSecondS3的实现即可:
const { S3Client } = require('@aws-sdk/client-s3'); const { Upload } = require('@aws-sdk/lib-storage'); // S3Client初始化逻辑保持不变 const s3 = new S3Client({ credentials: { accessKeyId: S3_API_KEY, secretAccessKey: S3_API_SECRET, }, region: S3_REGION, signatureVersion: 'v4', }); const uploadToFirstS3 = async (stream) => { const uploadTask = new Upload({ client: s3, params: { Bucket: S3_BUCKET_NAME, Key: 'some-key', Body: stream, }, // 可选配置,可根据业务调整 partSize: 10 * 1024 * 1024, // 单个分块大小,最小为5MB queueSize: 4, // 并行上传的分块数量 }); await uploadTask.done(); return true; };
额外说明
Upload类底层自动使用S3分块上传API,不需要提前读取整个流获取总大小,边接收流数据边拆分分块上传,全程在内存中处理,不会写入本地磁盘,和你原有v2版本的行为、性能完全一致。
内容的提问来源于stack exchange,提问作者Xapadoan
相关产品推荐
相关产品推荐

