1. 程式人生 > 其它 >js 大檔案分割/分片上傳

js 大檔案分割/分片上傳

 

 

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>uploadFile</title>
    <style></style>
  </head>
  <body>
    <input type="file" id="file" multiple />
    <br />
<br /> <button id="btn">上傳</button> <script> var uploadFile; document.querySelector("#file").addEventListener( "change", (e) => { var files = e.target.files; if (!files.length) return; uploadFile = new CutFileAndUpload({ files, apiUpload: (fileData)
=> { //介面請求 返回當前檔案資料 /** * fileData = { file: file, //當前檔案 succeed: 0, //已經上傳的片數 shardSize: this.size, //以2MB為一個分片 shardCount: 0, //總片數 start: 0, //擷取開始位置 end: 0, //擷取結束位置 }
*/ //構造一個表單 表單欄位根據後端介面而定 let fdata = new FormData(); //計算切割檔案單個分片 let base64 = fileData.file.slice(fileData.start, fileData.end); // fdata.append("base64", base64, fileData.file.name); // fdata.append("name", fileData.file.name); // fdata.append("total", fileData.shardCount); //總片數 // fdata.append("numbers", fileData.succeed + 1); //當前是第幾片 //介面請求 setTimeout(() => { //更新檔案資料 uploadFile.updateFileData(); }, 2000); }, progress: (progress, total) => { //progress 當前檔案進度百分比 //total 總進度百分比 console.log(progress, total); }, success: () => { //上傳成功回撥 console.log("全部上傳完成"); e.target.value = ""; }, }); }, false ); document.querySelector("#btn").addEventListener( "click", () => { uploadFile.uploadFile(); }, false ); /** * * @param {*} options */ function CutFileAndUpload(options) { this.files = options.files || []; //要上傳的檔案列表 this.progress = options.progress; //上傳進度 this.success = options.success; //成功回撥 this.apiUpload = options.apiUpload; this.fileArr = []; //檔案列表切割後的檔案資料 this.fileIndex = 0; //上傳到第幾個檔案 this.size = 2 * 1024 * 1024; //分片單位 以2MB為一個分片 this.uploading = false; //上傳狀態 this.cutFile(); } CutFileAndUpload.prototype = { constructor: CutFileAndUpload, cutFile() { var files = this.files; if (!files.length) { console.log("請選擇要上傳的檔案"); return; } for (var i = 0; i < files.length; i++) { var file = files[i]; let fileData = { file: file, succeed: 0, //已經上傳的片數 shardSize: this.size, //分片單位 shardCount: 0, //總片數 start: 0, //擷取開始位置 end: 0, //擷取結束位置 }; fileData.shardCount = Math.ceil( fileData.file.size / fileData.shardSize ); //總片數 this.fileArr.push(fileData); } }, uploadFile() { if (!this.fileArr.length) { console.log("請選擇要上傳的檔案"); return; } var fileData = this.fileArr[this.fileIndex]; //計算每一片的起始與結束位置 fileData.start = fileData.succeed * fileData.shardSize; fileData.end = Math.min( fileData.file.size, fileData.start + fileData.shardSize ); //計算檔案單個分片 // let base64 = fileData.file.slice(fileData.start, fileData.end); // console.log(fileData); this.uploading = true; //介面請求 this.apiUpload && this.apiUpload(fileData); }, updateFileData() { //更新檔案資料 var fileData = this.fileArr[this.fileIndex]; fileData.succeed++; var progress = parseInt( (fileData.succeed / fileData.shardCount) * 100 ); var total; if (fileData.succeed === fileData.shardCount) { //單個檔案上傳完成 this.fileIndex++; total = parseInt((this.fileIndex / this.fileArr.length) * 100); this.progress && this.progress(progress, total); if (this.fileIndex == this.fileArr.length) { //列表的全部檔案上傳完成 this.uploading = false; this.fileIndex = 0; this.fileArr = []; this.success && this.success(); } else { this.uploadFile(); } } else { total = parseInt((this.fileIndex / this.fileArr.length) * 100); this.progress && this.progress(progress, total); this.uploadFile(); } }, }; </script> </body> </html>