如何手写一款KOA的中间件来实现断点续传 (2)

实现代码:

function splitBuffer(buffer,sep) { let arr = []; let pos = 0;//当前位置 let sepPosIndex = -1;//分隔符的位置 let sepPoslen = Buffer.from(sep).length;//分隔符的长度,以便确定下一个开始的位置 do{ sepPosIndex=buffer.indexOf(sep,pos) if(sepPosIndex==-1){ //当sepPosIndex是-1的时候,代表已经到末尾了,那么直接直接一口读完最后的buffer arr.push(buffer.slice(pos)); }else{ arr.push(buffer.slice(pos,sepPosIndex)); } pos = sepPosIndex+sepPoslen }while(-1!==sepPosIndex) return arr } 前端部分: H5中fileAPi的slice方法

slice之前是用于数组的一个方法,现在文件也可以用slice来分割拉,不过需要注意的是这个方法是一个新的api,也就是很多old的浏览器无法使用。

用法很简单:

//初始位置,长度 //这里的File对象是一个Blob,一个类似于二进制的流,所以这里是以字节为单位的。 File.slice(startByte, length); JS的原生AJAX实现方式XMLHttpRequest

新建一个XMLHttpRequest

xhr = new XMLHttpRequest();

打开一个post为请求的链接

xhr.open("post", "/submit", true);

配置onreadystatechange,捕获请求链接的状态。

xhr.onreadystatechange = function(){ //xhr.readyState //处理完成的逻辑 }; readyState 意义
0   初始化  
1   加载中  
2   加载完成  
3   部分可用  
4   加载完成  

准备工作都做好了,最后send一下,请求链接。

xhr.send(表单数据);

下面一节会写如何生成send中的表单数据

封装表单数据FormData

FormData的使用很友好,就是按照健值一个个配对就可以了。

var formData = new FormData(); formData.append("test", "I am FormData"); formData.append("file", 你选择的文件);

虽然简单,但是却可以模拟post的数据格式send给服务器。

详细用法,点我

断点续传 主要逻辑

写了这么多有关之后开发断点续传的相关知识点,我们可以动手开始写了。断点续传的逻辑并不复杂大概就是这样的:

客户端client 服务器端server
我想上传一个文件   ok,no problem,不过你只能用post传给我  
我的文件很大直接form提交可以吗   有多大,如果很大的话,一旦我们的连接断开,我们就前功尽弃了啊!慎重啊!  
well,well,我把我的文件slice成一小块一小块慢慢给你行了吧   来吧baby~,我不介意你多来几次  
第一部分send   接受中...  
等待中...   接受完毕,处理接受的Blob,处理完毕已写入,你可以传第二部分了~  
第二部分send   接受中...  
等待中...   接受完毕,处理接受的Blob,处理完毕已写入,你可以传第三部分了~  
...   ...  
...   终于结束了,我去处理下你的文件  
...   ok~传送成功  
断点续传client端的处理方式

从上述逻辑来看,这个前端的流程可以分为:

确定文件大小,根剧相同的长度切片

根据切片的数量,进行回调上传

切分文件

断点续传是客户端主动发送,服务器端被动接受的一个过程,所以这里是在客户端进行一个文件的切分,把文件根据range的大小进行切分,range的大小可以自定义。这里我为了防止每次上传切片都要计算位置,所以提前把所有的位置都放入了currentSlice的数组之中。然后按顺序取位置。注意:这边切分全部是以字节为单位的计算。

createSlices(){ let s=0,e=-1,range=1024; for(let i = 0;i<Math.ceil(this.file.size/range);i++){ s=i*range,e=e+range e=e>this.file.size-1?this.file.size-1:e; this.currentSlice.push([s,e]) } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdsyz.html