前言:文件断点续传,指的是在进行上传或者下载时,将文件分割成几块,每一块都单独上传或下载,如果某一块由于网络原因或者其他因素,导致上传或下载失败,那么可以从已经上传或下载的部分继续进行上传下载未完成的部分,节省时间,提高效率。此外,也支持暂停上传或下载。
文件秒传,指的是当用户上传一个已被上传过(自己或他人上传到同一个文件服务器中)的文件时,文件能够直接跳过上传过程,达到秒传的效果。其中的原理就是,用户上传文件时,会同时发送文件的md5值,服务端会进行相应查找匹配,如果有相同的md5,则返回通知文件已上传过服务器,不必再次上传,实现秒传。
本文主要讲断点续传之上传和秒传的实现
在 HTML5 普及之前,上传基本是通过flash实现的,断点续传的实现也相对麻烦,本篇就不涉及啦,下面进入主题。
通过 HTML5 File API 进行文件分割,File 接口是基于 Blob 对象
Blob 对象表示不可变的类似文件对象的原始数据,包含两个属性 size (Blob对象中数据的大小)和 type (Blob对象包含数据的MIME类型)。还拥有一个方法 slice,返回一个新的 Blob对象,包含了源 Blob对象中指定范围内的数据。
对文件进行分割,使用的就是 File 继承于 Blob 对象的 slice 方法。
对文件分割完成后,则进行上传,上传时客户端和服务端都会保存当前文件块的编号。上传完成后,则进行下一块上传
以上主要是前端需要实现,再来看下服务端(采用node.js实现)是如何将文件块接收,并拼接成完整文件的
在服务端实现过程中,主要的难点是如何接收前端传输的参数,前端参数都是通过 FormData 传到服务端,服务端需要对参数进行解析,这里采用 connect-multiparty 库进行解析参数。参数接收完成后,则进行文件的写入操作。
秒传的实现就较为简单了,主要是上传第一块文件块时,会将文件的md5值传到服务端,然后进行查找匹配。难点在于如何获取文件的md5值。获取文件的md5主要是使用 spark-md5 库。
此外,对于超大文件(1G以上)需要做下优化处理,因为浏览器读取文件流的能力有限,如果一次性读取超大文件的文件流(FileReader),那么浏览器占用内存会瞬间飙升,系统会变得卡顿,甚至直接浏览器崩溃。
优化的方案是:将文件进行切割分块,一块一块地读取到文件流中,然后计算MD5值
源码:https://github.com/Peterlhx/html5-resume 如果对你有用,欢迎star~