分片下载MD5校验不一致需定位具体出错片段,关键是在分片粒度校验且前后端逻辑对齐:服务端预提供各分片MD5,前端严格按相同偏移、长度切片并用ArrayBuffer计算校验,边下载边比对,失败仅重试该片;拼接用Blob确保字节顺序,最终再校验总MD5。

分片下载后 MD5 校验不一致,本质是**某一片段在传输、写入或拼接过程中字节流发生了改变**,不能简单重试整个文件,而要定位到具体哪一片出错。关键在于:校验必须在分片粒度上做,且前后端处理逻辑严格对齐。
分片下载前先约定校验方式
不要等下载完再算总 MD5——大文件拼接后才发现不一致,无法定位问题。应在下载发起前就明确:
- 服务端为每个分片单独提供一个 独立的 MD5 值(例如返回 JSON 中包含
chunks: [{url: "...", md5: "abc123..."}, ...]) - 前端按相同规则切片(如每片 4MB),且起始偏移、长度、是否包含边界字节必须和服务端完全一致
- 统一编码与读取方式:所有分片用
FileReader.readAsArrayBuffer()读取,避免readAsBinaryString引入 UTF-16 编码污染
边下载边校验每一片
每个分片请求完成后立即计算其 ArrayBuffer 的 MD5,比对服务端下发的该片 MD5:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 校验失败时,只重下这一片,不干扰其他已完成分片
- 使用 SparkMD5.ArrayBuffer() 直接计算 ArrayBuffer(无需转字符串),高效且无编码风险
- 示例代码片段:
const hash = SparkMD5.ArrayBuffer(arrayBuffer);
if (hash !== expectedMd5) { /* 记录失败索引,触发重试 */ }
拼接时确保字节顺序与完整性
所有分片校验通过后,拼接成完整文件再算一次总 MD5 用于最终确认。注意:
立即学习“Java免费学习笔记(深入)”;
- 用
new Blob(chunks, {type: mimeType})拼接,不是字符串拼接或 base64 合并 - 若需导出为 File 对象,可用
blob.slice(0, blob.size, mimeType)并指定 name,避免丢失原始类型信息 - 拼接后的 Blob 再调一次 SparkMD5.ArrayBuffer(),和接口返回的
fileMd5字段比对
常见导致不一致的隐藏原因
即使逻辑正确,以下细节仍可能让 MD5 对不上:
-
HTTP Range 请求头被代理/CDN 修改:检查响应的
Content-Range是否与请求的 range 完全匹配,尤其注意末尾是否多读或少读 1 字节 -
服务端自动 gzip 压缩未关闭:分片响应若被压缩,前端拿到的是压缩后字节,MD5 必然错——需在请求头加
Accept-Encoding: identity -
浏览器缓存干扰:对同一 URL 的分片请求加上唯一查询参数(如
?t=1726452834123)或禁用缓存(cache: 'no-store')

















