S3分段上传文件损坏无法打开问题求助
S3分段上传后文件损坏的排查与修复
问题现象
用AWS SDK v3实现S3分段上传,通过预签名URL让前端上传文件分段,整个流程(初始化、上传、完成)都没报错,但下载后的文件打不开,提示已损坏。
核心问题及修复方案
1. 缺少分段ETag验证(最常见原因)
前端上传每个分段后,必须把响应头里的ETag(注意去掉前后的引号)和对应的PartNumber一起传给后端。如果你的parts参数只传了PartNumber没传ETag,S3无法正确拼接分段,直接导致文件损坏。
修复:
- 前端上传分段后,从响应头提取
ETag并处理:async function uploadPart(signedUrl, blob, partNumber) { const res = await fetch(signedUrl, { method: 'PUT', body: blob }); if (!res.ok) throw new Error(`分段${partNumber}上传失败`); const etag = res.headers.get('ETag').replace(/"/g, ''); // 去除ETag的双引号 return { PartNumber: partNumber, ETag: etag }; } - 后端调用
CompleteMultipartUpload时,确保parts数组每个元素都包含PartNumber和ETag。
2. 分段大小不符合S3要求
S3规定:除最后一个分段外,其他分段必须至少5MB(5242880字节)。如果前端拆分的非最后分段小于这个值,S3可能不会报错,但拼接后的文件会损坏。
修复:
- 前端拆分文件时,设置非最后分段大小≥5MB,最后一个分段可以小于5MB
- 后端可以在生成预签名URL前,校验分段大小是否合规(如果前端传递了分段大小参数)
3. 前端请求方法或数据编码错误
UploadPartCommand生成的预签名URL要求用PUT方法上传,如果前端用了POST/GET等其他方法,或者对分段数据做了错误编码(比如base64转码后未正确解码),会导致上传的分段内容异常。
修复:
- 前端必须用PUT请求调用预签名URL,请求体直接传分段的二进制数据(Blob/ArrayBuffer)
- 不要对分段数据做额外编码转换,确保上传的内容和原文件分段完全一致
4. 分段顺序或编号错误
虽然你的代码里用了orderBy(parts, ["PartNumber"], ["asc"])排序,但如果前端传递的PartNumber本身有误(比如重复、缺失、编号不连续),还是会导致拼接顺序错误,文件损坏。
修复:
- 前端拆分文件时,按顺序给分段编号(从1开始连续递增)
- 后端在处理
parts时,校验PartNumber是否连续无重复
代码调整示例
后端CompleteMultipartUpload的parts参数格式
确保传入的parts是如下格式:
const validParts = [ { PartNumber: 1, ETag: '"a1b2c3d4"' }, // S3接受带/不带引号的ETag,前后端保持一致即可 { PartNumber: 2, ETag: '"e5f6g7h8"' } ];
内容的提问来源于stack exchange,提问作者hemant jangid
相关产品推荐
相关产品推荐

