Node.js使用AWS S3 SDK v3调用PutObject上传对象时报NotImplemented错误
错误产生原因
S3的PutObject接口不支持Transfer-Encoding: chunked分块传输请求头。
你使用graphql-upload拿到的文件可读流默认不包含总长度信息,AWS SDK v3在传递未知长度的流作为请求体时,会自动添加Transfer-Encoding: chunked头,触发S3返回该错误。
修复方案
分两种场景选择对应的修复方式:
场景1:上传文件普遍小于100MB(小文件场景)
可以先把可读流转换为Buffer,AWS SDK可直接从Buffer中获取内容长度,自动设置正确的Content-Length头,避免触发分块传输逻辑。
修改后代码示例:
const { createReadStream, mimetype, filename } = file; const { buffer } = require('stream/consumers'); // Node.js 16+ 内置模块,低版本可自行用concat-stream等库实现 const fileBuffer = await buffer(createReadStream()); const prefix = encodeURIComponent(folder) + '/'; const uploadParam = { Bucket: bucket, Key: `testing`, Body: fileBuffer, ContentType: mimetype, }; await s3.send(new PutObjectCommand(uploadParam));
场景2:上传大文件,避免占用过多内存
使用AWS SDK官方提供的分片上传工具Upload,它会自动将未知长度的流切分为分片上传到S3,不需要提前获取文件总长度,也不会触发分块传输头。
首先安装依赖:
npm install @aws-sdk/lib-storage
修改后代码示例:
const { createReadStream, mimetype, filename } = file; const { Upload } = require('@aws-sdk/lib-storage'); const fileStream = createReadStream(); const prefix = encodeURIComponent(folder) + '/'; const uploadParam = { Bucket: bucket, Key: `testing`, Body: fileStream, ContentType: mimetype, }; // 执行分片上传 const upload = new Upload({ client: s3, params: uploadParam }); await upload.done();
内容的提问来源于stack exchange,提问作者Kyaw Zin Thiha
相关产品推荐
相关产品推荐

