必须用 web worker 分片计算大文件 md5:主线程切片(2–8mb)、逐块读取并传 arraybuffer 给 worker;worker 用 sparkmd5 增量哈希,完成后返回结果;主线程控制并发、及时释放内存;md5 用于服务端秒传校验与断点续传。

直接在主线程算大文件 MD5,页面会卡死几秒甚至十几秒,用户点不动按钮、进度条不动、体验极差。必须用 Web Worker 把计算挪到后台线程,界面完全不卡,还能准确拿到文件指纹用于秒传判定。
分片读取 + 增量哈希是基础
不能把整个大文件一次性读进内存(会爆内存、触发浏览器崩溃),必须边切片边计算:
- 推荐切片大小:2–8 MB(根据文件体积动态调整,比如 ≤20MB 用 1MB,≥200MB 用 6–8MB)
- 用 File.prototype.slice 分块,配合 FileReader.readAsArrayBuffer 逐块读取
- 在 Worker 中使用 SparkMD5.ArrayBuffer 的增量接口(append() + end()),避免重复构造对象
Worker 脚本要能安全加载和通信
子线程不能直接 import 模块,需用 importScripts 加载本地脚本:
- 把 spark-md5.min.js 内容复制到 public/spark.js
- Worker 文件开头写:importScripts('/spark.js')
- 接收主线程传入的 File 对象(注意:File 可结构化克隆,能安全传递)
- 计算完成后调用 postMessage({ md5: 'xxx', totalChunks: 123 }) 返回结果
主线程控制流程与并发
避免多个 FileReader 或 Worker 同时争抢资源导致内存飙升或响应延迟:
- 用 Promise 队列或最大并发数(如 3 个)控制分片读取节奏
- 每个分片读取完成(onload)后,将 e.target.result(即 ArrayBuffer)通过 worker.postMessage({id: i, data: buffer}) 发送给 Worker
- 主线程监听 onmessage,按 id 更新对应分片状态,收到全部结果后合并为整体 MD5
- 计算完立即释放 ArrayBuffer 引用(buffer = null),帮助 GC 回收内存
校验结果用于秒传与续传
拿到整体 MD5 后不是直接上传,而是先和服务端确认是否已存在:
- 前端发起请求:POST /api/upload/check?fileMd5=xxx
- 服务端查库或对象存储中是否存在同 MD5 的完整文件
- 命中则返回 { code: 200, url: '/files/xxx.mp4' },前端跳过上传,完成“秒传”
- 未命中才进入切片上传流程,同时带上各分片 MD5(如 X-Part-MD5)供服务端校验,支持断点续传
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











