我整理的大文件上传方案设计

📝 大文件上传前端设计文档

一、方案概述与设计依据

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 携带 fileHashfileSizefileName
  • 后端响应处理:

    • 秒传成功(例如 200): 文件已存在,通知用户完成上传。

    • 需继续上传(例如 201): 后端返回已完成的分片索引列表[0, 1, 5, ...])。

  • 待传队列生成: 前端根据总分片数和后端返回的列表,过滤掉已完成的分片,生成待上传的分片队列

2. 并发请求上传
  • 并发控制: 使用 Promise 队列异步任务限制工具,将并发数限制在合理范围(如 3-6),防止瞬时网络拥塞。

  • 请求封装: 每个分片使用 FormData 封装,通过 POST 请求发送到 /upload/chunk 接口。

  • 数据验证: 请求中包含 fileHashchunkIndexchunkTotal,确保后端能正确接收和暂存分片。

2.3 环节三:后端接收与合并(收尾阶段)

当前端待上传队列清空(所有分片上传成功)时,进入收尾阶段。

1. 合并通知
  • 触发时机: 最后一个分片上传成功后。

  • 请求通知: 前端发送文件合并请求POST /upload/merge,携带 fileHashchunksTotal

  • 后端处理: 后端接收通知后,根据 fileHash 找到所有暂存的分片,按 chunkIndex 顺序合并成完整文件,并清理临时分片存储空间。


三、异常处理机制

强大的异常处理能力是实现断点续传和稳定上传的关键。

3.1 断点续传(Resume Upload)

  • 实现机制: 完全依赖于后端的状态

  • 触发场景: 用户刷新页面、浏览器崩溃后重新打开、或上传任务主动暂停后恢复。

  • 处理流程: 在任何需要恢复上传的场景,始终重新执行 "分片校验与续传查询" 的预检请求,获取最新的已上传分片列表,重新生成待传队列并继续上传。

3.2 失败重传(Retry Mechanism)

  • 触发场景: 单个分片请求因网络波动、超时或服务器临时错误而失败。

  • 处理逻辑:

    1. 检测到分片上传失败(非 200 状态码)。

    2. 将该分片重新加入待上传队列,自动重试 N 次(推荐 N=3)。

    3. 如果重试 N 次后仍然失败,则暂停整个上传任务,并向用户展示明确的错误信息。

3.3 上传暂停和取消

1. 暂停上传
  • 前端操作: 使用浏览器原生的 AbortController API 终止所有正在进行的 fetchXMLHttpRequest 请求。

  • 状态维护: 暂停后,当前已完成的分片信息已保留在后端,等待用户点击"恢复"时进行断点续传。

2. 取消上传
  • 前端操作: 终止所有正在进行的请求。

  • 后端通知: 向后端发送 清理请求 (例如 DELETE /upload/abort 携带 fileHash),通知后端删除所有已暂存的分片数据,彻底释放服务器空间。


四、前端优化与用户体验

优化点 目标 备注
实时进度条 实时反馈上传进度。 总进度条应基于 已完成分片数/总分片数 计算。
错误提示 明确告知用户问题所在。 失败时应区分是网络问题、文件问题还是服务器问题。
资源清理 优化内存使用。 当一个分片上传成功后,可以考虑释放该分片对应的 Blob 对象在前端的引用。
并发数调整 适应不同网络环境。 允许用户在设置中调整并发数,或根据用户带宽动态调整。
相关推荐
@大迁世界1 天前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路1 天前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug1 天前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu121381 天前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中1 天前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 天前
GDAL 实现矢量合并
前端
hxjhnct1 天前
React useContext的缺陷
前端·react.js·前端框架
冰暮流星1 天前
javascript逻辑运算符
开发语言·javascript·ecmascript
前端 贾公子1 天前
从入门到实践:前端 Monorepo 工程化实战(4)
前端
菩提小狗1 天前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全