背景
相信很多开发者都遇到过这样的场景:用户上传一个几百MB甚至几个GB的文件,传了99%突然网络中断,一切重头再来;或者浏览器卡死、页面无响应,用户体验直接崩盘。
普通表单上传的三大痛点:
上传失败率高:网络波动、超时、服务器限制,大文件极易上传失败
用户体验差:长时间等待无反馈,失败后必须重传,用户心态爆炸
救救你的文件服务器吧,它快顶不住了
第一步:前端分片 —— 化整为零,各个击破
解决大文件上传的核心思路就是分而治之——把一个大文件切成很多小分片,逐个上传。
实现原理:
使用 HTML5 的 Blob.slice() 方法,这是浏览器原生支持的 API
一般每个分片设置为 5MB 左右(可根据实际情况调整)
为每个分片计算唯一的 MD5 值作为标识,防止上传错乱
const CHUNK_SIZE = 5 * 1024 * 1024; // 5MB
function createChunks(file) {
const chunks = [];
for (let i = 0; i < file.size; i += CHUNK_SIZE) {
chunks.push({
chunk: file.slice(i, i + CHUNK_SIZE),
index: Math.floor(i / CHUNK_SIZE)
});
}
return chunks;
}
为什么是 5MB?
太小会增加请求数量,太大又失去了分片的意义。5MB 是工业界的经验值,兼顾了请求数量和单个请求的成功率。
第二步:实现秒传 —— 零传输,体验拉满
秒传是最能提升用户体验的功能!同一个文件,只要有人传过,后面的用户就可以瞬间完成上传。
实现原理:
先发送一个"预检请求"给后端:"这个文件你有吗?"
后端检查是否存在该文件,如果存在 → 直接返回"上传成功"
秒传的价值:
第三步:断点续传 —— 断了?从断点继续!
这是整个方案最核心的功能,也是解决"传了99%失败"这个千古难题的关键。
实现原理:
上传中断后(网络断开、页面刷新、主动暂停),前端再次发起请求
async function resumeUpload(fileMd5, chunks) {
// 获取已上传的分片列表
const uploadedList = await getUploadedChunks(fileMd5);
// 过滤出未上传的分片
const pendingChunks = chunks.filter(chunk =>
!uploadedList.includes(chunk.index)
);
// 只上传未完成的分片
return uploadChunks(pendingChunks);
}
用户价值:不管传了多少,断了就从断点继续,再也不用从头再来!
第四步:后端合并 —— 聚沙成塔,校验完整性
所有分片上传完成后,最后一步就是把这些小分片拼成完整的大文件。
实现原理:
后端按分片序号(index)顺序,将所有分片拼接成完整文件
与前端传来的原始 MD5 值进行比对,确保文件完整无损
完整性校验为什么重要?
网络传输过程中可能出现丢包、数据损坏。MD5 比对能确保最终文件和源文件100% 一致,这是企业级系统的必备保障。
三个高阶优化点
上面四步是基础方案,下面这三个优化点,就是区分"普通开发"和"高级开发"的关键了。
优化一:控制前端并发数
问题:如果一次性把所有分片的请求都发出去,几百个请求同时发,浏览器直接崩溃!
解决方案:限制并发数,每次只传 3-5 个分片。一个分片上传完成后,再从队列里取下一个。
const MAX_CONCURRENT = 3; // 最大并发数
async function uploadWithConcurrency(chunks) {
const queue = [...chunks];
const running = [];
while (queue.length > 0) {
if (running.length < MAX_CONCURRENT) {
const chunk = queue.shift();
const promise = uploadChunk(chunk).then(() => {
running.splice(running.indexOf(promise), 1);
});
running.push(promise);
} else {
await Promise.race(running);
}
}
}
优化二:后端异步处理
问题:如果后端接收分片时在内存中处理,大文件会把内存撑爆。
解决方案:
优化三:定时垃圾清理
问题:很多用户上传到一半就放弃了,这些"半截分片"会一直占用磁盘空间。
解决方案:
总结
| | |
|---|
| 前端分片 | | |
| 秒传 | | |
| 断点续传 | | |
| 后端合并+MD5校验 | | |
| 并发控制 | | |
| 异步处理 | | |
| 垃圾清理 | | |
该文章在 2026/6/17 9:50:08 编辑过