分片上传,断点续传,还有秒传

前端精髓

共 2251字,需浏览 5分钟

 · 2022-01-21

分片上传

为什么需要分片上传


如果文件体积比较大,或者网络条件不好时,上传的时间会比较长(要传输更多的报文,丢包重传的概率也更大),用户不能刷新页面,只能耐心等待请求完成。


分片上传的核心思想


利用H5提供的原生File对象,由于File对象是特殊类型的Blob, File接口也继承了Blob接口的属性,分片上传的核心思想就是利用File继承Blob接口的Blob.slice方法。


Blob.slice方法可以将我们的文件切分为多个单个的切片,分片上传的思想就是利用slice APi将文件分割成多个切片,然后利用浏览器多进程的特性进行并发上传。


为了后端能正确的拼接文件,我们需要为每一个文件提供一个唯一的标识符,以及标记每一个切片的顺序。


标识符一般通过以下两种方式获取


根据文件名、文件长度等基本信息进行拼接,为了避免多个用户上传相同的文件,可以再额外拼接用户信息如uid等保证唯一性。


根据文件的二进制内容计算文件的hash,这样只要文件内容不一样,则标识也会不一样,缺点在于计算量比较大。


document.getElementById('file').addEventListener('change', function () {    var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,        file = this.files[0],        chunkSize = 2097152,                             // Read in chunks of 2MB        chunks = Math.ceil(file.size / chunkSize),        currentChunk = 0,        spark = new SparkMD5.ArrayBuffer(),        fileReader = new FileReader();
fileReader.onload = function (e) { console.log('read chunk nr', currentChunk + 1, 'of', chunks); spark.append(e.target.result); // Append array buffer currentChunk++;
if (currentChunk < chunks) { loadNext(); } else { console.log('finished loading'); console.info('computed hash', spark.end()); // Compute hash } };
fileReader.onerror = function () { console.warn('oops, something went wrong.'); };
function loadNext() { var start = currentChunk * chunkSize, end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); }
loadNext();});

断点续传


即使将大文件拆分成切片上传,我们仍需等待所有切片上传完毕,在等待过程中,可能发生一系列导致部分切片上传失败的情形,如网络故障、页面关闭等。由于切片未全部上传,因此无法通知服务端合成文件。这种情况下可以通过断点续传来进行处理。


主要思路

1.在切片上传成功后,保存已上传的切片信息。2.当下次传输相同文件时,遍历切片列表,只选择未上传的切片进行上传。3.所有文件分片上传完毕,调用接口通知服务端进行合并。


对于切片信息的保存一般采用以下两种方式。


可以通过locaStorage等方式保存在前端浏览器中,这种方式不依赖于服务端,实现起来也比较方便,缺点在于如果用户清除了本地文件,会导致上传记录丢失。


服务端本身知道哪些切片已经上传,因此可以由服务端额外提供一个根据文件context查询已上传切片的接口,在上传文件前调用该文件的历史上传记录。

秒传

在上传切片前将文件的基本信息发送至服务端进行验证,判断该文件是否需要重新上传,如果已经上传就返回上传结果,实现秒传。


验证方法

1.文件名。2.文件最后修改的时间(File文件对象的一个属性 lastModified)。3.文件hash值。


浏览 2
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报