📝 大文件上传前端设计文档
一、方案概述与设计依据
1.1 设计目标
基于文件分块和断点续传机制,实现高效、稳定、可恢复的大文件上传功能,解决传统上传模式下大文件易失败的问题。
1.2 核心流程(图示解析)
| 环节 | 核心目标 | 关键技术 |
|---|---|---|
| 前端拆分文件 | 将大文件切分为可控的小块,并建立唯一身份标识。 | File.prototype.slice(),Web Worker 计算 MD5。 |
| 分片校验与上传 | 利用标识符查询已完成分片,实现秒传和续传。 | 预检请求,并发控制。 |
| 后端接收与合并 | 保证所有分片完整,通知后端合并。 | 后端接口设计(合并通知)。 |
| 异常处理 | 保证上传任务的完整性和用户体验。 | 断点续传逻辑,AbortController。 |
二、前端详细实现流程
2.1 环节一:前端拆分文件(准备阶段)
这是上传任务的启动阶段,核心是将大文件转化为可管理的上传单元,并赋予其唯一标识。
1. 文件分片
-
API 使用: 采用浏览器原生的
File.prototype.slice()方法。 -
分片大小: 固定为 5MB (需根据服务器性能调整),将
File对象切分成Blob数组。 -
分片信息: 每个分片(Chunk)对象应包含:
-
chunkIndex: 分片索引(从 0 开始)。 -
chunkTotal: 文件总分片数。 -
chunkBlob: 实际的二进制数据块。
-
2. 文件唯一标识(MD5)
-
唯一标识: 计算整个文件的 MD5 值 (
fileHash) 作为文件的全局唯一 ID。 -
性能优化(关键): MD5 计算是 CPU 密集型操作,为避免浏览器主线程阻塞,必须在 Web Worker 线程中进行计算。
-
数据流向:
fileHash将贯穿整个上传过程,作为后端识别文件身份的依据。
2.2 环节二:分片校验与上传(核心阶段)
通过 fileHash 预先与后端通信,确定上传起点,并以并发方式高效传输数据。
1. 分片校验与续传查询
-
预检请求: 在正式上传前,前端向后端发送一个校验请求:
POST /upload/verify携带fileHash、fileSize、fileName。
-
后端响应处理:
-
秒传成功(例如 200): 文件已存在,通知用户完成上传。
-
需继续上传(例如 201): 后端返回已完成的分片索引列表 (
[0, 1, 5, ...])。
-
-
待传队列生成: 前端根据总分片数和后端返回的列表,过滤掉已完成的分片,生成待上传的分片队列。
2. 并发请求上传
-
并发控制: 使用 Promise 队列 或 异步任务限制工具,将并发数限制在合理范围(如 3-6),防止瞬时网络拥塞。
-
请求封装: 每个分片使用
FormData封装,通过POST请求发送到/upload/chunk接口。 -
数据验证: 请求中包含
fileHash、chunkIndex、chunkTotal,确保后端能正确接收和暂存分片。
2.3 环节三:后端接收与合并(收尾阶段)
当前端待上传队列清空(所有分片上传成功)时,进入收尾阶段。
1. 合并通知
-
触发时机: 最后一个分片上传成功后。
-
请求通知: 前端发送文件合并请求 :
POST /upload/merge,携带fileHash和chunksTotal。 -
后端处理: 后端接收通知后,根据
fileHash找到所有暂存的分片,按chunkIndex顺序合并成完整文件,并清理临时分片存储空间。
三、异常处理机制
强大的异常处理能力是实现断点续传和稳定上传的关键。
3.1 断点续传(Resume Upload)
-
实现机制: 完全依赖于后端的状态。
-
触发场景: 用户刷新页面、浏览器崩溃后重新打开、或上传任务主动暂停后恢复。
-
处理流程: 在任何需要恢复上传的场景,始终重新执行 "分片校验与续传查询" 的预检请求,获取最新的已上传分片列表,重新生成待传队列并继续上传。
3.2 失败重传(Retry Mechanism)
-
触发场景: 单个分片请求因网络波动、超时或服务器临时错误而失败。
-
处理逻辑:
-
检测到分片上传失败(非 200 状态码)。
-
将该分片重新加入待上传队列,自动重试 N 次(推荐 N=3)。
-
如果重试 N 次后仍然失败,则暂停整个上传任务,并向用户展示明确的错误信息。
-
3.3 上传暂停和取消
1. 暂停上传
-
前端操作: 使用浏览器原生的
AbortControllerAPI 终止所有正在进行的fetch或XMLHttpRequest请求。 -
状态维护: 暂停后,当前已完成的分片信息已保留在后端,等待用户点击"恢复"时进行断点续传。
2. 取消上传
-
前端操作: 终止所有正在进行的请求。
-
后端通知: 向后端发送 清理请求 (例如
DELETE /upload/abort携带fileHash),通知后端删除所有已暂存的分片数据,彻底释放服务器空间。
四、前端优化与用户体验
| 优化点 | 目标 | 备注 |
|---|---|---|
| 实时进度条 | 实时反馈上传进度。 | 总进度条应基于 已完成分片数/总分片数 计算。 |
| 错误提示 | 明确告知用户问题所在。 | 失败时应区分是网络问题、文件问题还是服务器问题。 |
| 资源清理 | 优化内存使用。 | 当一个分片上传成功后,可以考虑释放该分片对应的 Blob 对象在前端的引用。 |
| 并发数调整 | 适应不同网络环境。 | 允许用户在设置中调整并发数,或根据用户带宽动态调整。 |