大文件上传逻辑梳理
大文件上传逻辑梳理
背景
如果文件太大,比如一个视频几个 G,直接上传,可能出现连接超时,也存在超过服务器允许上传文件的大小限制。
为了解决这个问题,我们可以将大文件进行分片上传,每次只用上传很小的一部分,然后再有后端去组装这些分片,就可以形成一个完整的文件。
方案
- 前端将大文件切片,拆分成一个一个的
chunk
。 - 将切片传递给后端,每个切片都带有唯一标识(hash)和索引值(index),以便于后端处理。
- 后端将切片进行组合。
实现过程
文件采用 Blob 格式,它表示原始数据,也就是二进制数据,同时提供了对数据截取的方法slice
,而 File 继承了Blob
的功能,所以可以直接使用此方法对数据进行分段。
整体流程:
- 将大文件进行分段,发送到服务器时携带一个标志,用于标识一个完整的文件。
- 服务端保存各段文件。
- 浏览器所有分片上传完成,给服务器发送一个合并文件的请求。
- 服务器根据文件标识、类型、各分片顺序进行文件合并。
- 删除分片文件。
前端逻辑实现
前端布局
1 |
|
文件切片
1 |
|
上传切片
1 |
|
后端逻辑实现
整体过程:
- 创建写入流
- 将切片转换成流
- 将切片流追加到写入流中
- 删除已经读取过的切片
- 将合并完成后的写入流生成对应的文件
将前端传过来的切片保存到磁盘
这里采用了multer
npm 包,更好的去处理FormData
数据。
1 |
|
读取切片、转换成文件流、将切片流追加到写入流
1 |
|
优化方案
- 前端切片:主线程去做切片卡顿,可以借助
web-worker
多线程切片,处理完成后交给主线程发送。 - 切片完成后,发送给后端,并将
blob
存储到IndexedDB
(为了防止切片完成,用户关闭了浏览器,导致切片丢失),用户下次进来之后,可以嗅探一下是否存在未上传的切片,如果有就继续上传。
待更新:断点续传、秒传
参考文章: