cos-js-sdk-v5分片上传 解析

1,158 阅读2分钟

官网分片上传api demo

官网例子中sliceUploadFile如下。

cos.sliceUploadFile({
    Bucket: 'examplebucket-1250000000', /* 填入您自己的存储桶,必须字段 */
    Region: 'COS_REGION',  /* 存储桶所在地域,例如ap-beijing,必须字段 */
    Key: '1.jpg',  /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */
    Body: fileObject,                /* 必须 */
    onTaskReady: function(taskId) {                   /* 非必须 */
        console.log(taskId);
    },
    onHashProgress: function (progressData) {       /* 非必须 */
        console.log(JSON.stringify(progressData));
    },
    onProgress: function (progressData) {           /* 非必须 */
        console.log(JSON.stringify(progressData));
    }
}, function(err, data) {
    console.log(err || data);
});

必要参数为key文件名和body file对象。具体的分片上传全过程则在sliceUploadFile函数内实现。

源码位置

源码根文件入口 ,暴露主要的cos 类(注意此处使用的是非标准class写法)其中在71行注册了高级方法,即sliceUploadFile。根据动态注册api,定位

实际sliceUploadFile方法在advance.js第7行

sliceUploadFile过程

以下画了大概的处理过程

cos分片上传过程.png

主要注意以下几点

  1. 获取文件大小,并计算要切片的Chunk大小。
  2. 通过File.slice对二进制文件进行切片,发起请求确认该文件的uploadId,并通过uploadId区分具体的上传任务,通过partNumber确定分片的位置。
  3. 每个切换Chunk需要md5计算对应的etag,此etag会在上传返回时的response header etag进行对比,确认文件是否一致。不一致则不标记上传成功。
  4. 异步上传chunk,并有节流处理。防止http连接被浏览器队头堵塞
  5. 对未上传成功的chunk进行重试
  6. 全部结束后,清理uploadId,并通知服务端上传结束

源码中还有更多实现细节,包括多个文件上传时uploadId管理等,不具体展开

sliceUploadFile执行后请求分析

sliceUploadFile执行后请求

总结

实现过程类似于tcp协议,有握手,队头用塞控制,滑动窗口,错误重传,数据包校验。因为分片上传是应用层进行分片,要实现可靠的协议,所以实现也需要在应用层进设计一套可靠的方案