应使用 slice() 分片读取大文件,每片1–5mb,读完立即释放 filereader;文件唯一id需基于分片哈希聚合生成;并发上传限3–5路,用promise队列控制,并通过content-range等头字段精准定位错误。

怎么用 FileReader 读取大文件的某一段
直接 readAsArrayBuffer 整个大文件会卡死页面,内存爆掉。必须切片读,每次只读一块。
- 先用
file.slice(start, end)截出二进制片段,注意它返回新Blob,不是修改原文件 -
start和end单位是字节,别用字符长度或行数去算 - 推荐每片 1–5 MB,太小增加 HTTP 请求次数,太大拖慢单次读取和内存释放
- 读完立刻释放
FileReader实例(设为null),否则多个并发读可能堆积 GC 压力
const chunk = file.slice(0, 2 * 1024 * 1024); // 2MB
const reader = new FileReader();
reader.onload = () => {
const buffer = reader.result; // ArrayBuffer
uploadChunk(buffer, 0);
};
reader.readAsArrayBuffer(chunk);
前端怎么生成稳定、可续传的文件唯一标识
不能用 file.name + file.size,重名文件或同名不同内容都会冲突;也不能依赖 lastModified,用户改系统时间就失效。
- 必须基于文件内容计算哈希,但全量计算太慢——用分片哈希:对每个 chunk 计算
SHA-256,再拼接所有 hash 做一次聚合(如SHA-256of concatenated hashes) - 浏览器里用
SubtleCrypto.digest(),别用第三方 JS 库,避免大包和兼容性问题 - 把文件名、大小、最后修改时间作为元数据存进上传请求体,用于服务端校验,但不参与 ID 生成
- 注意:
File对象在页面刷新后不可复用,ID 必须在用户选中文件后立即生成并缓存到sessionStorage
怎么控制并发分片上传又不压垮浏览器
发 100 个 fetch 并发请求,轻则卡 UI,重则触发 Chrome 的连接池限制(默认 6 个 per host),大量请求排队或被 cancel。
- 硬限并发数,建议 3–5,用 Promise 队列控制,不用
Promise.all一把梭 - 每个分片请求加
signal,方便用户点击“暂停”时快速 abort,避免残留 pending 请求 - 服务端返回 413 或 422 时,别重试整个分片,先检查是否是
Content-Range格式错误或 token 过期 - 上传中监听
upload.onprogress,但别频繁更新 DOM,用requestIdleCallback节流渲染
服务端返回 400 但没说清哪片错了,前端怎么定位
常见于 Content-Range 解析失败、MD5 校验不匹配、或分片序号跳变。前端日志往往只显示 “Bad Request”,看不出根因。
- 确保请求头带
Content-Range: bytes 0-1048575/10485760,格式必须严格,空格、斜杠、单位一个都不能错 - 服务端返回的错误体里通常有
chunk_index或range字段,前端要主动解析响应体(即使状态码非 2xx),而不是只看 status - 本地调试时用
curl -v对比正常/异常请求头差异,重点比对Content-Type(该是application/octet-stream)、Content-Length、Authorization - 别假设服务端一定按顺序接收分片——前端必须自己维护
uploadedChunks = new Set([0, 1, 3]),靠返回确认,不靠顺序推断
分片上传真正难的不是切和发,而是错误恢复时如何精准还原现场:哪片没发、哪片发了但服务端没写盘、哪片 hash 对不上却没报错。这些都得靠前后端约定好幂等字段和原子校验点,缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











