5

XMLHttpRequest实现HTTP协议下文件上传断点续传

 3 years ago
source link: https://www.zhangxinxu.com/wordpress/2013/11/xmlhttprequest-ajax-localstorage-%e6%96%87%e4%bb%b6%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

by zhangxinxu from https://www.zhangxinxu.com
本文地址:https://www.zhangxinxu.com/wordpress/?p=3754

一、网盘割据的时代

不知大家有没有观察过,在秋季,也就是眼下这个时间,当阵风挂起的时候,地上的落叶就会以一个接一个,翻滚着一同被吹走,这就是“跟风”。老祖宗确实很有智慧,造出来的词语源于生活,又高于生活。

眼下,又是另一波跟风之势——“网盘”,犹如当年团购一样。不过,网盘还是有一定的技术和其他成本,因此,还不像团购那样“落叶漫天飞舞”的状态。但是,各大公司相继介入,可谓又是另外一场群雄之战。

秋风扫落叶 一吹一大片

我并不是专业的产品人,也不是公司的决策者,因此,面对一些纷杂繁芜的现象,自己无心去深入,也不会去评价。立志做个技术人,因此,我所关心的可能就是技术实现,至于孰对孰错,恩怨情仇,公关伎俩,生死天命等一概作云烟从眼前飘过。

网盘中有个很重要的,可以说是核心的功能,就是文件上传,So,本文就来说说这个上传,如何在HTTP协议下实现文件的断点续传呢?

二、文件断点续传的实现

目前从实用技术角度讲,文件上传的断点续传实现主要是借助客户端,例如,我们首次进入微云,会看到下图所示的“控件安装”提示:

微云控件安装的提示

百度网盘似乎有文件上传暂停的功能,这似乎是借助swfUpload实现的。

也就是,这些带续传功能的上传都不是使用HTTP协议实现的,也就是不是传统的网页技术(HTML+CSS+JS)实现的。

然,times are changing, 事物发展,时代变化。以前的一些所谓的“不能”、“不可能”都将成为过去。

上月一篇独苗文章介绍了XMLHttpRequest level 2(下简称Ajax 2.0)中的一些支持的数据格式,如果稍微关注,应该知道,Ajax 2.0中最大的变化之一就是对二进制数据的支持,而且提供了一个可以直接处理二进制数据的方法——slice方法。

JS中的字符串有slice方法,数组也有。Ajax 2.0经过一些变化后,现在也和数组、字符串的slice方法语法完全一致了。于是,我们就可以把二进制数据流想象成一些连续的字符串数据,并对这些二进制数据进行slice处理。

比方说怎样的场合呢?

PHP默认似乎有个最大文件上传的限制post_max_size,我的本地看了下,是64M.

PHP默认最大上传限制

此时,我们想一次性传一个80M的动作片精华片段,就会以失败告终。

但是,有了slice方法,我们可以把文件分割,比方说,每20M作为一个请求发送出去,后台再把这些二进制数据拼合成一个完整文件。

slice(0, 20); slice(20, 40); slice(40, 60); slice(60)

还有一个很重要的场合就是断点续传

文件传输是个具有时间周期的过程,从玩三国杀的离线率可以看出,掉线什么的是常有的事情。显然,传文件必定会存在传着传着就死在99%位置的情况。

你想啊,大鼻孔姐的片子想放到网盘里,随时随地可以欣赏。结果看着进度条等了40分钟,好不容易传到99%,突然断电…………开机后,发现又要重传,是不是小弟弟要气得短小软?显然,后果很严重哈~

因此,对于大文件而言,断电续传功能很重要。有了Blob数据格式的slice方法,一切都变得简单了。

我的思路是这样的,有两条:
1. 浏览器记住(如localStorage)最近一次成功传输的位置;当再次上传这个图片的时候,直接从浏览器存储的位置开始传。
2. 浏览器不做任何事情,在上传之前先去后台走一遍,看看目前此文件是否存在,以及存在的大小,返回给浏览器,然后浏览器再决定上传的起始位置。

理性的分析以及实践的结果表明,第二种思路可行性更高。//zxx: 并不一定是最好的思路,您可以自己想出更精彩的实践方法

如果用文字举例的话就是:
某老师的视频是80*1024*1024B, 我们每次传1024*1024B,也就是1M,假设传了79M了,结果大脚一抖,电源关掉有木有!某老师就这样随风逝去了……

用户重新开机,决定再次传这个80M的视频。当用户选择了这个文件后,我们先去后台走一圈,把当前已经传好的文件大小反馈给客户端(Ajax 1.0就可以),JS拿反馈大小和源文件大小一比对,奶奶的,残缺啊!于是,就从残缺位置slice,这里就是:

file.slice(79*1024*1024)

接着之前的只传了1M就OK啦!于是,断点续传实现。

由于网页本身的局限性,我们没法直接触发本地文件的上传。因此,目前而言,断点文件还是要用户选择(相比客户端上传软件多了这一步)。

三、文件断点续传的实践

Ajax实现的文件断点续传demo截图 张鑫旭-鑫空间-鑫生活

您可以狠狠地点击这里:HTTP协议下Ajax实现的文件断点续传demo

说明:

  1. 上demo可以说是一个比较完善的上传体验,有删除,重传,续传,进度条等常用功能。
  2. 基于Ajax 2.0的二进制文件传输实现,因此,IE10+,Chrome以及Firefox等浏览器支持。另外JS原生,无外部依赖。
  3. 空间的流量月月吃紧,经常溢出不够用,因此,为了节约成本,只允许最大200K的文件。所以,大家想要测试断点续传效果,可以通过工具,把自己的浏览器速度限制到10~20K每秒。
  4. demo页面每100K就会对文件进行一次分割上传,因此,100~200K大小文件会有看到2次上传请求。PS:实际开发时候,应该至少1M一次分割。
  5. 为了直观表现断点上传的功能,我会截一个本地的视频给大家演示,并原声重现。
  6. 后台PHP很简单,就是追加二进制数据,file_put_contents方法有个FILE_APPEND选项,直接追加,很好用的!
  7. 正好研究了下开源协议,这里请容我练个:demo页面中的JS+CSS+HTML源代码遵循GPL协议,即您可以任意复制,修改,但是,只能作为学习或私人项目使用,不能作为商业软件的一部分去出售。如有疑问,可[email protected]联系。

其他一些技术细节,懂的人不说也知道是怎么回事,不懂的人要花很大功夫斟酌表达才可以。然,目前时机不成熟,付出收益比略低,因此,这里不具体叙述,有问题欢迎邮箱联系。

add on 2016-04-13
目前线上demo貌似文件都无法上传成功,感觉可能和服务商的服务器设置有关,安全限制还是什么的,我也没深究,我本地是好的,可以秒传。大家不要太在意这个细节。

add on 2017-09-19
今天偶然看到服务商有个设置,我开启了下,嘿,可以上传了。

add on 2018-11-11
截止到今天,已经有不下于3人索要源码,都是5块钱成交的,含JS源码和PHP代码。如果你也有意向,欢迎邮箱联系([email protected]),邮件内容为求源码,愿意支付就可以了。

add on 2020-03-30

求源码的好多人,也愿意付费,但是每次我都要一个一个邮件回复,折腾的时间算下来成本远远不止5块钱,所以决定了,走诚信支付形式,想要源码自己下面地址下载然后支付即可。

源码在下面:

链接:https://share.weiyun.com/5apGYTk 密码:2p3mrm

支付这里:

give me five

下面视频演示下断点续传的效果:
因为半夜三更录的视频,老婆大人已经安然就寝,所以自己声音比较小,发音也不太准,貌似被优酷搞糊了,大家凑合看看吧~~

四、说点题外话

上月本人只更新了一篇文章。有一周是整周的培训。然后除了研究现在这个Ajax断点续传,还在做一个自己的开源项目(已经用了两周了,本周应该可以结束)。

本人最近有在纠结专利与开源的事情。我司申请专利很是方便,而且公司鼓励,且对个人发展有很有帮助,我显然是要积极做这些事情的。但是,个人价值观中很重要的一点就是要留下什么,因此,自己是非常喜欢共享东西的。于是就存在一个矛盾,有些东西,例如一些创新的想法或者实现方式,如果成为的专利,就不好拿出来随意分享了,因为,自己申请的专利不是自己的而是公司的,自己完全没有把控权。头疼~~

不过,今天例会跟组里前辈沟通了下,算是想通了。这样子,自己平时业余时间研究的东西,即使很赞,很具有专利性,我也会及时和大家一起探讨与进步;如果是实际工作发现的创新性想法,则走专利路线,技术封闭。我举得这样的权衡应该是很不错的,不知大家的看法如何呢?

哈哈,今天特地研究了下开源版权的问题,学到了不少,各种License都大致了解了一点,文中好像就有体现了,

博客所有技术文章遵循CC协议,即署名、非商业性使用、相同方式共享、禁止演绎。

一些开源插件等遵循其他协议,回头补上~~

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK