js断点续传

版权声明:三和小钢炮 https://blog.csdn.net/fwx426328/article/details/83655093

一、 js断点续传的思路

对于一个大文件,可以将其切割成适当的小文件,提交给后台,再由后台合并成大文件。
这样做法的好处有:
(1)化整为零,可以防止文件上传中断而导致整个文件都需要重新上传的杯具问题。
(2)分成小文件,可以利用ajax的多线程,同时提交多个小文件,从而提升上传速度。

前端
1.切片是否存在
2.上传切片n
3,合并切片
后台

二、 断点续传实现

1. 接口文档

要实现断点续传,后台必须实现下面接口:


(1)文件上传接口
接口说明:
此接口用于上传文件切片,file参数是文件切片的内容。后台在保存的时候,可以将同一个文件的切片保存到一个文件夹下,所以原文件名称是可能需求的参数。为了保证切片的唯一性,id作为文件签名是必须的。由于并发的提交,为了保证文件切片的顺序,所以要加上index。
注意:后台在记录文件签名的时候,是可以采用多种方法记录的。但是一定要考虑文件的并发提交对数据存储和查询的影响。


请求方式: post
入参:

{
  "file": "Blob",
  "filename": "1.text",
  "index": 2,
  "id": "cdee9e473d48764864028e38936bb62d"
}
参数 含义
file 文件切片
filename 文件名称
index 切片序号
id 文件唯一识别,这里采用md5生成

返回值:

{
  "code": 1
}
参数 含义
code 返回码 1-成功 0-失败

(2)合并文件接口
接口说明:
合并接口即把切片文件合并,在合并文件的时候,注意考虑切片的序列号。
请求方法: post
入参 :

{
  "filename": "1.text"
}
参数 含义
filename 文件名称

返回值:

{
  "code": 1
}
参数 含义
code 返回码 1-成功 0-失败

(3)查询文件接口
接口说明:
查询文件是否存在,如存在,前端不再发起ajax上传。
请求方式: post
入参:

{
  "id": "cdee9e473d48764864028e38936bb62d",
  "filename": "1.text",
  "index": 2
}
参数 含义
id 文件签名
filename 文件名称
index 切片序号

返回值:

{
  "code": 1,
  "isExist": 1
}
参数 含义
code 返回码 1-成功 0-失败
isExist 是否存在 1-存在 0-不存在

2. fileupload.js原理

(1)文件切割
js的Blob对象提供了slice方法,而File对象继承于Blob,则File文件就可以切割为小分片后提交给后台。


(2)文件签名
小分片的提交,就需要判断小分片是否存在,我们可以在文件分片的时候把文件签名带上,通过比较文件签名是否存在,来判断文件是否已经上传。
补充:md5可以使用spark-md5.js来生成。


(3)http的并发
普通的文件上传,只会发起一个http连接。但主流浏览器http最大并发连接数,一般都达到了6个。显然资源的利用率不够,把文件切割成分片,则可以并发的提交文件,以达到浏览器资源的充分利用。


3. fileupload.js使用

fileupload.js对接了上面接口。

(1)实例化Fileupload
fileupload.js构造函数如下:

var fileupload = new Fileupload({
  upload: './php/upload.php',
  query: './php/query.php',
  merge: './php/merge.php',
  cache: false,
  slicesize: 4 * 1024,
  thread: 4,
  filesign: SparkMD5.ArrayBuffer.hash
});

参数含义:

参数 是否必须 含义 缺省
upload 上传接口url -
query 查询接口url -
merge 合并接口url -
cache 是否使用本地缓存 true
slicesize 切片大小 4M
thread 线程数 3
filesign 文件签名算法 例如md5

说明:

  1. cache 设置为true,则fileupload.js会将文件签名记录到浏览器的localStorage里面,则查询后台之前,会先检查本地记录,如果本地记录存在,则不会上传,本地记录不存在,则调用后台查询。
  2. slicesize 此处为切片大小的设置,理论上讲,切片过大则不能实现断点的功能,而切片过小,则计算和交互又太过于频繁而降低性能。那么一定存在一个切片大小的最优解。
  3. thread 线程数,此时的线程指的是浏览器ajax线程,在实际经验中,chrome并发表现优于ie,这里可以根据浏览器类型,自行设置。
  4. filesign 文件签名算法,任何文件签名都有发生碰撞的可能,fileupload.js做出任何实现都是考虑不完善的。同时,hash算法的抗碰撞性和性能是冲突的。所以根据产品特性,做出合理的文件签名算法才是合理的。

(2)上传文件
fileupload.js上传文件操作如下:

var files = document.getElementById("file");
var file = files.files
fileupload.addFile(file);
fileupload.upload();

addFile接口可以使多个文件,upload方法被调用则开始启动上传。


(3)事件监听
fileupload.js事件监听如下:

fileupload.on({
  success: function() {
    alert('上传完成');
  },
  complete: function(filename) {
    alert(filename + '上传完成');
  },
  query: function(data) {
    console.log(data);
  },
  merge: function(data) {
    console.log(data);
  },
  upload: function(data) {
    console.log(data);
  },
  progress: function(progress) {
    progress = 100 * progress;
    document.getElementById("progess").value = progress.toFixed(2);
  }
});
事件 含义
success 所有上传文件成功
complete 单个文件上传成功
query 查询接口返回事件
merge 合并接口返回事件
upload 上传接口返回事件
progress 进度

fileupload.js也可以下面监听事件:

fileupload.on('progress', function (progress) {
  console.log(progress);
});

(3)暂停
fileupload.js切片操作都是异步实现。其暂停后会持续地推迟下一个分片的动作以阻止上传的行为,直至暂停取消。
理论上暂停操作会轻微的影响性能,但不会和主线程竞争资源。

fileupload.setPause(isPause);

isPause:
true为暂停,
false为继续


三、 fileupload.js源码

demo后台由php完成

github地址:
https://github.com/fwx426328/resumebreakpoint

代码量:400行

猜你喜欢

转载自blog.csdn.net/fwx426328/article/details/83655093