
前端大文件上传网上的大部分文章已经给出了解决方案,核心是利用 Blob.prototype.slice 方法,和数组的 slice 方法相似,文件的 slice 方法可以返回原文件的某个切片
预先定义好单个切片大小,将文件切分为一个个切片,然后借助 http 的可并发性,同时上传多个切片。这样从原本传一个大文件,变成了并发传多个小的文件切片,可以大大减少上传时间
另外由于是并发,传输到服务端的顺序可能会发生变化,因此我们还需要给每个切片记录顺序
服务端负责接受前端传输的切片,并在接收到所有切片后合并所有切片
这里又引伸出两个问题
第一个问题需要前端配合,前端在每个切片中都携带切片最大数量的信息,当服务端接受到这个数量的切片时自动合并。或者也可以额外发一个请求,主动通知服务端进行切片的合并
第二个问题,具体如何合并切片呢?这里可以使用 Nodejs 的 读写流(readStream/writeStream),将所有切片的流传输到最终文件的流里
<template></template>断点续传的原理在于前端/服务端需要记住已上传的切片,这样下次上传就可以跳过之前已上传的部分,有两种方案实现记忆的功能
第一种是前端的解决方案,第二种是服务端,而前端方案有一个缺陷,如果换了个浏览器就失去了记忆的效果,所以这里选后者
利用一个第三方库 spark-md5, 它可以根据文件内容计算出文件的hash值;
考虑到如果上传一个超大文件,读取文件计算hash是非常耗时的,会引起页面UI阻塞,导致页面假死,所以利用web-worker在worker线程计算hash,这样用户可以继续在主界面进行交互
大文件上传
断点续传