断点续传在对于传送一些比较大的文件的时候比较重要,网上也有很多断点续传的代码,但是那些一般都是比较简单的,因为断点续传的原理并不难,前端利用slice方法将文件进行分割,后端代码接收到每个片的代码,再拼接即可。网上代码之所以比较简单,因为他们都是直接把图片放在服务器的,显然这样不够专业,现在的图片基本上都托管在图片服务器上,例如七牛等,因此我们要的是如何和他们对接好断点续传,下面是和七牛对接好的demo:

七牛图片断点续传 gif 七牛图片断点续传

难点分析

七牛难道没有官方接口文档吗?还要我在这里写?有肯定是有的,地址: 七牛断点续传文档。我之所以写这篇文章,是因为它的文档比较坑,没有具体的demo,而且上传的类型也不是我们平常用到的,导致我们总是上传不成功。

根据文档我们知道,七牛的做法是将大文件分成块(block)和片(chunk)来上传的,大致如下:

为什么要这么分呢?因为块和片是有不同属性的,块是可以同时上传的,但是一个块中的片是必须一个接着一个上传,等所有的块完毕,就可以创建文件了。

当然,我们根据文档自己大致划分了块和片如下:

background Layer 1 chunk1 chunk2 chunk3 chunk4 block1 1M 1M 1M 1M chunk1 block2 1M (4M) (1M)

因为官方的说法是每个block大小为4MB,最后一个不大于4MB,因此我们将一个4MB的block分成4分,每份为1MB,也就是一个chunk为1MB,注意一个block中的所有chunk之和必须等于block,而且标准的block大小就是4MB,如果你想设置3MB或者5MB必须要去修改后端的配置,如果只是前端修改这个尺寸的话,在合并所有块的时候会报错。

我们第一步是要创建一个块,创建块的时候要注意Content-Type:application/octet-stream,我们要利用ajax上传一个二进制流,注意这里用原生的ajax,关键代码如下:

创建块的时候有几个参数:第一,这个块有多大,例如一个5MB的图片,需要创建两个块,一个为4MB,一个为1MB;第二,第一个片的内容,这里需要注意上传的是二进制流,我们选择的文件属于file blob,需要先用readAsArrayBuffer将blob变成二进制流;第三,需要一个Authorization,注意,这玩意不等于七牛的token,关系为Authorization='UpToken '+token。

创建完之后,会返回一个ctx和offset,当你创建下一个片的时候,需要带上上一个片的ctx和offset。

当创建完所有的片之后,就要通过mkfile接口将他们组装起来,文档上写的时候每个块最后一个片的ctx,这里注意,一定要按照块的顺序组装,否则报错,还要注意,这里的content-type为text/plain,这玩意不需要带key,直接将所有的ctx组装(用逗号分割)上传就好了。

断点续传

上面讲了如何做七牛的分片上传,断点续传这里主要体现在暂停/开启和刷新页面上。

当你点击暂停之后,会将当前正在发送的请求abort,取消请求,同时保存被取消的ajax以便恢复,关键代码如下:

刷新页面的断点续传主要是根据file.name来在cookie中生成一条记录,这个里面记录了片的ctx和offset,关键代码如下:

当你在下次准备上传片或者块的时候看看有没有存在的,如果有,那么直接用cookie中的,如果没有,则请求。

这里要注意,刷新页面的断点续传操作是:第一次你选了a.jpg,然后上传一半的时候刷新页面,这个时候再选a.jpg才会出现刷新的断点续传,因为我们是不能直接把图片放入缓存的,缓存的空间也就几MB而已,而一张图片可能有几十MB,因此不能直接将图片存入缓存,而只能再第二次选择相同图片时触发。

最后

看文章好像说的很简单的样子,真的只有等你自己写的时候才知道什么叫绝望了,报了无数个错,没有可参考的文章,只能自己去猜哪个地方可能有问题,哎,希望这篇文章能帮到你。

好吧,在v友的指导下还是找出了js sdk,里面有分片上传的代码,地址:js sdk,看来下次还是要先找文档,文档找错了也挺尴尬的。

DEMO下载

点击下载 [0积分]一共下载0

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字