AWS SDK v2可上传PDF至S3,v3上传后S3无对应文件
问题排查与解决
1. 显式指定PDF的Content-Type参数
AWS SDK v3和v2在自动识别Blob的MIME类型上存在行为差异:
- v2会自动从Blob对象中读取
type属性作为Content-Type,但v3在部分场景下(比如Blob通过特定逻辑构造)可能无法自动识别。 - 若上传时未显式设置
Content-Type: 'application/pdf',S3可能将PDF标记为application/octet-stream,甚至导致数据解析异常,最终文件未被正确存储。 - 解决方式:在
PutObjectCommand参数中强制指定Content-Type:
const command = new PutObjectCommand({ Bucket: 'your-bucket-name', Key: 'target-file.pdf', Body: yourBlob, ContentType: 'application/pdf' // 显式指定MIME类型 });
2. 检查Blob的流/数据处理逻辑
PDF文件的Blob可能存在数据读取不完整的情况,尤其是当Blob来自前端FormData或特定转换逻辑时:
- v3的
PutObjectCommand对Body的处理更严格,如果传入的Blob流未被完全消费,可能返回成功响应但实际未上传完整数据。 - 解决方式:将Blob转换为Uint8Array/Buffer后再上传,确保数据完整性:
// 将Blob转换为Buffer const arrayBuffer = await yourBlob.arrayBuffer(); const fileBuffer = Buffer.from(arrayBuffer); const command = new PutObjectCommand({ Bucket: 'your-bucket-name', Key: 'target-file.pdf', Body: fileBuffer, ContentType: 'application/pdf' });
3. 针对大PDF启用自动分块上传
如果PDF文件大小超过5MB(S3 PutObject的默认上限),v2会自动触发分块上传,但v3的基础PutObjectCommand不支持自动分块:
- 此时直接用
PutObjectCommand上传大PDF,可能返回成功但实际S3未存储文件(因为分块上传未完成)。 - 解决方式:使用
@aws-sdk/lib-storage包中的Upload类处理大文件,它会自动处理分块逻辑:
import { Upload } from '@aws-sdk/lib-storage'; import { S3Client } from '@aws-sdk/client-s3'; const s3Client = new S3Client({ /* 你的配置 */ }); const upload = new Upload({ client: s3Client, params: { Bucket: 'your-bucket-name', Key: 'target-file.pdf', Body: yourBlob, ContentType: 'application/pdf' } }); upload.on('httpUploadProgress', (progress) => { console.log(progress); }); await upload.done();
4. 对比v2与v3的参数一致性
检查v3代码中所有上传参数是否与v2完全匹配:
- 确认
Bucket、Key、ACL、StorageClass等参数完全一致,避免因参数差异导致文件存储在其他位置或被过滤。
内容的提问来源于stack exchange,提问作者Michael Gradek
相关产品推荐
相关产品推荐

