断点续传:顾名思义,继续上次断开的点,继续上传。
思路整理:
- 拿到文件,对文件进行fingerprint = md5(file),得到文件指纹。
- 将指纹保存服务器。
- 切割文件,分段上传,每次上传一段。
- 服务器根据指纹进行索引判断文件上传进度,直到文件的全部片段上传完毕。
以下文字没有完整的代码,只有基础理论,伸手党绕道。
1. 读取文件
// 这里只演示单文件上传过程。 var input = document.querySelector('input'); input.addEventListener('change', function() { var file = this.files[0]; //这里是有一个坑的,部分设备(华为部分机型)无法获取文件名称,和文件类型,这个在最后给出解决方案 var fileType = file.type; // getFileType(file, fileType => {}) });
2. 获取文件指纹
var fingerprint = md5(file);
3. 文件切割
var reader = new FileReader(); reader.readAsArrayBuffer(file); reader.addEventListener("load", function(e) { //每10M切割一段,这里只做一个切割演示,实际切割需要根据file.size进行循环切割. let size = 1024 * 1024 * 10; var slice = e.target.result.slice(0, size); });
4. h5上传一个(一片)文件
// 一般情况下不需要getFileType。 getFileType(file, fileType => { var formdata = new FormData(); formdata.append('fingerprint', fingerprint); // 指纹作为文件名,并拼接文件类型(也可以在服务器断进行文件类型处理) formdata.append('filename', fingerprint + '.' + fileType); // 做好切片索引,把索引作为切片名称 // 第一片为了保存指纹,可以尽量切小一点。 formdata.append('0', slice); var xhr = new XMLHttpRequest(); xhr.addEventListener('load', function () { //xhr.responseText }); xhr.open('POST', ''); xhr.send(formdata); xhr.addEventListener('progress', updateProgress); xhr.upload.addEventListener('progress', updateProgress); }); function updateProgress(event) { if (event.lengthComputable) { //进度条 } }
无法获取文件类型的设备解决方案
首先在:http://www.garykessler.net/li...查找对应文件的头信息
这里只给出了常见的图片和视频的文件类型判断
function getFileType(file, back) { var name = file.name; var type = ''; if (name) { var lastIndex = name.lastIndex('.') type = name.substring(lastIndex + 1) back(type); return; } // 如果系统无法获取文件类型,则读取二进制流,对二进制进行解析文件类型 var imgType = { 'ff d8 ff': 'jpg', '89 50 4e': 'png', '0 0 0 14 66 74 79 70 69 73 6F 6D': 'mp4', '0 0 0 18 66 74 79 70 33 67 70 35': 'mp4', '0 0 0 0 66 74 79 70 33 67 70 35': 'mp4', '0 0 0 0 66 74 79 70 4D 53 4E 56': 'mp4', '0 0 0 0 66 74 79 70 69 73 6F 6D': 'mp4', '0 0 0 18 66 74 79 70 6D 70 34 32': 'm4v', '0 0 0 0 66 74 79 70 6D 70 34 32': 'm4v', '0 0 0 14 66 74 79 70 71 74 20 20': 'mov', '0 0 0 0 66 74 79 70 71 74 20 20': 'mov', '0 0 0 0 6D 6F 6F 76': 'mov', '4F 67 67 53 0 02': 'ogg', '1A 45 DF A3': 'ogg', '52 49 46 46 x x x x 41 56 49 20': 'avi', } // 用最长的作为截取边界 var size = Object.keys(imgType).map(i => i.split(/\s+/).length).sort()[0] var reader = new FileReader(); reader.readAsArrayBuffer(file); reader.addEventListener("load", function (e) { var result = e.target.result if (!result || result.length < size) { back('') return; } var slice = result.slice(0, size); var view = new Uint8Array(slice); var arr = view.map(v => v.toString(16)) type = imgType[arr.join(' ')]; if (!type) { // 处理一个特殊情况:忽略第4-8位 arr = arr.map(function (v) { if (i > 3 && i < 8) { return 'x'; } return v; }); type = imgType[arr.join(' ')]; } back(type); }); }
总结:有了切割上传,有了文件唯一标识信息(文件md5)断点续传只不过是后台的一个小小的判断逻辑而已。
未来,前端,大有可为
有些小伙伴不是太清楚后台的小小的判断是怎么做的:
这里贴一张图给大家参考,自己手画,有点丑,将就下。
参考文章:http://blog.ncmem.com/wordpress/2023/10/19/js%e5%ae%9e%e7%8e%b0%e6%96%87%e4%bb%b6%e5%88%87%e7%89%87%e4%b8%8a%e4%bc%a0%ef%bc%8c%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0/
欢迎入群一起讨论
标签:断点续传,66,js,74,file,70,var,上传,79 From: https://www.cnblogs.com/songsu/p/17774391.html