思路很簡單,拿到文件,保存文件惟一性標識,切割文件,分段上傳,每次上傳一段,根據惟一性標識判斷文件上傳進度,直到文件的所有片斷上傳完畢。html
如下文字沒有完整的代碼,只有基礎理論,伸手黨繞道。前端
var input = document.querySelector('input'); input.addEventListener('change', function() { var file = this.files[0]; });
var md5code = md5(file);
var reader = new FileReader(); reader.readAsArrayBuffer(file); reader.addEventListener("load", function(e) { //每10M切割一段,這裏只作一個切割演示,實際切割須要循環切割, var slice = e.target.result.slice(0, 10*1024*1024); });
var formdata = new FormData(); formdata.append('0', slice); //這裏是有一個坑的,部分設備沒法獲取文件名稱,和文件類型,這個在最後給出解決方案 formdata.append('filename', file.filename); 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 checkFileType(type, file, back) { /** * type png jpg mp4 ... * file input.change=> this.files[0] * back callback(boolean) */ // http://www.garykessler.net/library/file_sigs.html var args = arguments; if (args.length != 3) { back(0); } var type = args[0]; // type = '(png|jpg)' , 'png' var file = args[1]; var back = typeof args[2] == 'function' ? args[2] : function() {}; if (file.type == '') { // 若是系統沒法獲取文件類型,則讀取二進制流,對二進制進行解析文件類型 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 (RIFF fileSize fileType LIST)(52 49 46 46,DC 6C 57 09,41 56 49 20,4C 49 53 54) ]; var typeName = [ 'jpg', 'png', 'mp4', 'mp4', 'mp4', 'mp4', 'mp4', 'm4v', 'm4v', 'mov', 'mov', 'mov', 'ogg', 'ogg', 'avi', ]; var sliceSize = /png|jpg|jpeg/.test(type) ? 3 : 12; var reader = new FileReader(); reader.readAsArrayBuffer(file); reader.addEventListener("load", function(e) { var slice = e.target.result.slice(0, sliceSize); reader = null; if (slice && slice.byteLength == sliceSize) { var view = new Uint8Array(slice); var arr = []; view.forEach(function(v) { arr.push(v.toString(16)); }); view = null; var idx = arr.join(' ').indexOf(imgType); if (idx > -1) { back(typeName[idx]); } else { arr = arr.map(function(v) { if (i > 3 && i < 8) { return 'x'; } return v; }); var idx = arr.join(' ').indexOf(imgType); if (idx > -1) { back(typeName[idx]); } else { back(false); } } } else { back(false); } }); } else { var type = file.name.match(/\.(\w+)$/)[1]; back(type); } }
checkFileType('(mov|mp4|avi)',file,function(fileType){ // fileType = mp4, // 若是file的類型不在枚舉之列,則返回false });
formdata.append('filename', md5code+'.'+fileType);
總結:有了切割上傳,有了文件惟一標識信息(文件md5)斷點續傳只不過是後臺的一個小小的判斷邏輯而已。app
有些小夥伴不是太清楚後臺的小小的判斷是怎麼作的:
這裏貼一張圖給你們參考,本身手畫,有點醜,將就下。this
後續我再畫一張完整的上傳流程圖給更新上來。spa