文章目录
- 1.大文件上传相关知识点
- 1.文件上传的数据类型是哪种?
- 2.大文件是怎么上传的?
- 3.如何区分不同的文件?(Hush)
- 4.Hush值是怎么算的?
- 5.遇到什么问题?(并发问题:控制多个请求的并发量)
- 6.后端需要提供哪些接口?
1.大文件上传相关知识点
1.文件上传的数据类型是哪种?
文件上传:如果不考虑文件大小上传,直接调用后端提供的post接口,文件上传必须用Formdata数据类型,Formdata里面携带File对象或Blob对象。
2.大文件是怎么上传的?
分片。
将大文件分片上传到服务器,服务器接收分片后,再将分片组装成一个文件。
如何分片?
核心是使用Blob对象的slice方法(File对象继承与Blob)。
主要流程是:
1.先将大文件用slice方法分片,将分好的片存到一个数组对象中。
2.计算该大文件的Hush值(利用文件内容计算,因此hush值都是唯一的,且不会根据文件名的改变就改变)
3.上传文件,如果该文件已经传过,则实现秒传,如果该文件只上传过部分(即上传了一部分切片,即断点重传),则过滤掉已经传过的切片,只上传未上传的切片。全部切片上传完成后,通知服务器做合并切片操作。
3.如何区分不同的文件?(Hush)
利用Hush,Hush值是通过大文件中的内容计算的,所以Hush值是唯一的,并且不会随着文件的名称改变而改变
4.Hush值是怎么算的?
spark-MD5包
切片过大算hush很费时间,下面的方法既保证了所有的切片都参与了计算,也能保证不耗费很长时间。
1.第一个和最后一个切片全部参与计算
2.中间剩余的切片分别在前面,后面,中间取2个字节参与计算
5.遇到什么问题?(并发问题:控制多个请求的并发量)
我们上传分片的时候是并发上传的,就是多个切片一起上传
但是当时忽略了多个请求同时发送会造成浏览器内存溢出,导致页面卡死了
比如谷歌浏览器,它默认并发数量只有6
所以要定义一个请求池来限制并发,如果请求池中已经有6个切片就要暂时阻塞住切片上传,必须等待请求池中有空余位置时,才能继续上传切片
伪代码如下:
const max = 6 //定义浏览器最大并发请求数
const taskpool = [] //请求池
if(taskpool.length===max){
await promise.race(taskpool)
}
注:Pomise.race的作用就是将多个异步任务包裹起来,当有一个完成的话,那么就会触发then事件。
6.后端需要提供哪些接口?
1.检查文件接口:接收参数:文件的hush值
文件已经上传过,通知客户端不需要再传,秒传成功
文件已经上传过,但是没有传完,告知客户端需要继续传,并告知需要从第几个分片开始传
文件没有上传过
2.上传文件接口:formData类型的file
接收分片文件,保存到临时目录
3.合并接口:接收参数:文件的hush值
合并文件分片,告知前端上传成功,并删除临时文件。