官网分片上传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过程
以下画了大概的处理过程
主要注意以下几点
- 获取文件大小,并计算要切片的Chunk大小。
- 通过File.slice对二进制文件进行切片,发起请求确认该文件的uploadId,并通过uploadId区分具体的上传任务,通过partNumber确定分片的位置。
- 每个切换Chunk需要md5计算对应的etag,此etag会在上传返回时的response header etag进行对比,确认文件是否一致。不一致则不标记上传成功。
- 异步上传chunk,并有节流处理。防止http连接被浏览器队头堵塞
- 对未上传成功的chunk进行重试
- 全部结束后,清理uploadId,并通知服务端上传结束
源码中还有更多实现细节,包括多个文件上传时uploadId管理等,不具体展开
sliceUploadFile执行后请求分析
总结
实现过程类似于tcp协议,有握手,队头用塞控制,滑动窗口,错误重传,数据包校验。因为分片上传是应用层进行分片,要实现可靠的协议,所以实现也需要在应用层进设计一套可靠的方案