前言
面试的时候老是被问,大文件上传逻辑,所以花了一天的时间实现了这个功能,登录+jwt认证+普通文件上传+大型文件上传
开始
演示效果

架构流程
1. 不能直接file.arrayBuffer()读取文件信息 使用slice Blob进行切片,得到chunks数组 合并所有块的数据内容,增量计算哈希[不会累积内存],得到文件的id【为秒传做准备,和文件做唯一性】
2. 准备工作完成,可以开始上传
3.
3-1.先请求秒传接口,查询文件是否在服务器存在
3-2.初始化分片上传接口
- 是否已有上传记录【查redis】,得到上传id,分片大小,已上传分片 {id:xxx, size:121, chunk: [1,2,3,4]}
3-3.上传分片
- 查询已上传分片[跳过]
- 请求分片接口, 获取上传信息[redis]
- 保存分片文件【根据 uploadId 创建临时分片目录,然后把当前上传的 chunk 保存到对应文件】
temp
└── a8f93c9d7e2b4f5a8c9d123456789abc
├── 0.chunk
├── 1.chunk
├── 2.chunk
更新redis已上传分片
上传完分片就自动执行下面
3-4.合并文件
- 请求合并文件接口
- 先获取上传信息 检查秒传【查询服务器是否存在】
- 合并文件[创建目录,合并分片,进库,删除临时分片]
用户选择文件
|
v
File对象(不读取全部内容)
|
v
Blob.slice 文件切片
|
v
增量计算文件Hash(MD5/SHA256)
|
v
fileId
|
+-----------+------------+
| |
v v
秒传检查 初始化上传
| |
已存在直接返回 创建uploadId
| |
v v
完成 上传分片
|
v
查询已上传chunk
|
跳过已经上传
|
v
上传当前chunk
|
v
Redis记录状态
|
v
全部分片完成
|
v
请求合并文件
|
v
合并 -> 入库 -> 删除临时文件