vue大文件分片上傳之simple-uploader.js的使用
關(guān)于大文件上傳
關(guān)于單個(gè)文件上傳:其實(shí)就是前端中的文件
通過(guò)http
傳到后端
,后端再寫(xiě)入服務(wù)器
的過(guò)程
那單個(gè)大文件分片
上傳:其實(shí)就是前端把大文件分成了好幾塊
,后端再多次寫(xiě)入服務(wù)器的過(guò)程
關(guān)于秒傳與斷點(diǎn)續(xù)傳
秒傳:其實(shí)就是服務(wù)器中存在這個(gè)文件了
,再次傳的時(shí)候就不重新上傳
了,前端直接顯示上傳成功
斷點(diǎn)續(xù)傳:其實(shí)就是文件傳了一部分
,剩下的還沒(méi)傳。這個(gè)時(shí)候根據(jù)上傳的偏移量offset
,把剩下的上傳
到服務(wù)器
前提知識(shí)
1. 前端使用spark-md5.js對(duì)文件進(jìn)行加密
import SparkMD5 from 'spark-md5' const spark = new SparkMD5.ArrayBuffer() //獲取文件二進(jìn)制數(shù)據(jù) var fileReader = new FileReader() fileReader.readAsArrayBuffer(file) //file就是獲取到的文件 //異步執(zhí)行函數(shù),fileReader.readAsArrayBuffer的回調(diào)函數(shù) fileReader.onload = function (e) { spark.append(e.target.result) const md5 = spark.end() console.log(md5) //打印結(jié)果這個(gè)文件會(huì)有一串唯一編碼類似下面 //4b4a94c7ff8953d7103515e91d432b0a }
2. simple-uploader.js的使用
// options常見(jiàn)配置 options: { // 上傳地址,若測(cè)試和真正上傳接口不是同個(gè)路徑,可以用函數(shù)模式。 // 如果是同一個(gè)路徑,一個(gè)get請(qǐng)求,一個(gè)post請(qǐng)求 target: "/fileStorage/upload", // 是否開(kāi)啟服務(wù)器分片校驗(yàn)。默認(rèn)為 true testChunks: true, // 真正上傳的時(shí)候使用的 HTTP 方法,默認(rèn) POST uploadMethod: "post", // 分片大小 chunkSize: CHUNK_SIZE, // 并發(fā)上傳數(shù),默認(rèn)為 3 simultaneousUploads: 3, /** * 檢測(cè)校驗(yàn)是md5加密以后的事情,整個(gè)上傳過(guò)程,只會(huì)執(zhí)行一次。 * 執(zhí)行一次以后,看是上傳完成,還是需要繼續(xù)上傳 * * 發(fā)起測(cè)試校驗(yàn)以后,所有分片都會(huì)進(jìn)入這個(gè)回調(diào) * * 判斷分片是否上傳,秒傳和斷點(diǎn)續(xù)傳基于此方法 * 如果后端返回的是true,代表秒傳 * 如果后端返回[1,2,3,4,5,6,7,8,9]等(分片信息),代表可以繼續(xù)上傳 * * * 我個(gè)人理解的停止上傳與繼續(xù)上傳就是斷點(diǎn)上傳 * * * 我個(gè)人理解這個(gè)方法是這樣的:分塊以后知道有幾塊了,再跟數(shù)據(jù)庫(kù)做比對(duì),知道是上傳完成了,還是需要繼續(xù)上傳 * api接口只走一次檢驗(yàn)方法,那如果是上傳完成了直接ok,如果是需要繼續(xù)上傳,那就接著上傳,組件再暴露出pause和resume方法,用于停止和繼續(xù)上傳。(api得到數(shù)據(jù)庫(kù)數(shù)據(jù)以后,每塊走這個(gè)方法,進(jìn)行對(duì)比。) */ checkChunkUploadedByResponse: (chunk, message) => { console.log("message,第一次test以后,返回來(lái)的數(shù)據(jù)", chunk.offset) // message是后臺(tái)返回 let messageObj = JSON.parse(message); let dataObj = messageObj.data; if (dataObj.uploaded !== null) { return dataObj.uploaded; } // 判斷文件或分片是否已上傳,已上傳返回 true // 這里的 uploadedChunks 是后臺(tái)返回 return (dataObj.uploadedChunks || []).indexOf(chunk.offset + 1) >= 0; }, parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) { //格式化時(shí)間 return parsedTimeRemaining .replace(/\syears?/, "年") .replace(/\days?/, "天") .replace(/\shours?/, "小時(shí)") .replace(/\sminutes?/, "分鐘") .replace(/\sseconds?/, "秒"); }, // 處理所有請(qǐng)求的參數(shù) // processParams:(params,file,chunk) => { // // 這里需要根據(jù)后端的要求,處理一些請(qǐng)求參數(shù) // // params.xxx = chunk.xxx // 比如一些需要在上傳時(shí),帶上測(cè)試校驗(yàn)返回的一些信息字段 // // return params; // } },
// 常用的回調(diào)函數(shù) <uploader ref="uploader" :options="options" :autoStart="false" :file-status-text="fileStatusText" @file-added="onFileAdded" @file-success="onFileSuccess" @file-error="onFileError" @file-progress="onFileProgress" class="uploader-example" >
分片上傳的思路
- 先對(duì)文件進(jìn)行md5加密。使用md5加密的優(yōu)點(diǎn)是:可以對(duì)文件進(jìn)行唯一標(biāo)識(shí)。在后端根據(jù)md5判斷文件是否存在。
- 向后臺(tái)發(fā)送第一次請(qǐng)求接口,且只發(fā)送一次,用于檢測(cè),接口里的數(shù)據(jù)就是我們已經(jīng)上傳過(guò)的文件塊。用于檢測(cè)是否需要秒傳或者繼續(xù)上傳
- 當(dāng)文件存在的話,就不用重新再上傳。(秒傳)
- 當(dāng)文件不存在的話,且對(duì)大文件進(jìn)行分片。比如一個(gè)100M的文件,我們一個(gè)分片是5M的話,那么這個(gè)文件可以分20次上傳。(checkChunkUploadedByResponse方法里面判斷)
- 當(dāng)文件不存在的話,且已經(jīng)上傳了一部分的。接著上傳(checkChunkUploadedByResponse方法里面判斷)
- 向后臺(tái)發(fā)送第二次請(qǐng)求接口,這時(shí)的請(qǐng)求才是正兒八經(jīng)的上傳請(qǐng)求。此時(shí),請(qǐng)求可以停止和繼續(xù)發(fā)。
前端文件切片常見(jiàn)的寫(xiě)法
// 文件切片需要是的參數(shù): 1. var fileSize = file.size; // 文件大小 2. var CHUNK_SIZE = 2 * 1024 * 1024; // 切片的大小 3. var chunks = Math.ceil(fileSize / chunkSize); // 獲取切片的個(gè)數(shù) 4. var currentChunk = 0; // 當(dāng)前分片下標(biāo) // 加載下一個(gè)分片的start與end const start = currentChunk * CHUNK_SIZE; const end = start + CHUNK_SIZE >= file.size ? file.size : start + CHUNK_SIZE;
// md5 加密 getFileMD5(file, callback) { // 使用SparkMD5,對(duì)文件進(jìn)行加密 let spark = new SparkMD5.ArrayBuffer(); let fileReader = new FileReader(); //獲取文件分片對(duì)象(注意它的兼容性,在不同瀏覽器的寫(xiě)法不同) let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice; // 當(dāng)前分片下標(biāo) let currentChunk = 0; // 分片總數(shù)(向下取整) let chunks = Math.ceil(file.size / CHUNK_SIZE); // 暫停上傳 file.pause(); // 第一次加載分片的方法 loadNext(); // fileReader.readAsArrayBuffer,讀完后的回調(diào)函數(shù) fileReader.onload = function (e) { // console.log("currentChunk :>> ", currentChunk); spark.append(e.target.result); if (currentChunk < chunks) { currentChunk++; loadNext(); } else { // 該文件的md5值 let md5 = spark.end(); // 回調(diào)傳值md5 callback(md5); } }; fileReader.onerror = function () { this.$message.error("文件讀取錯(cuò)誤"); file.cancel(); }; // 加載下一個(gè)分片 function loadNext() { const start = currentChunk * CHUNK_SIZE; const end = start + CHUNK_SIZE >= file.size ? file.size : start + CHUNK_SIZE; // 文件分片操作,讀取下一分片(fileReader.readAsArrayBuffer操作會(huì)觸發(fā)onload事件) fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end)); } },
// @file-added="onFileAdded" 回調(diào)函數(shù) onFileAdded(file, event) { console.log("onFileAdded方法執(zhí)行了__flx",event) /* * 第一步,判斷文件類型是否允許上傳 * */ // todo 判斷文件類型是否允許上傳 /* * 第二步:計(jì)算文件 MD5,并恢復(fù)上傳 * */ this.getFileMD5(file, (md5) => { console.log('MD5回調(diào)函數(shù)') if (md5 !== "") { // 修改文件唯一標(biāo)識(shí) file.uniqueIdentifier = md5; // 請(qǐng)求后臺(tái)判斷是否上傳 // 恢復(fù)上傳 file.resume(); } }); },
后端常見(jiàn)的寫(xiě)法
// 校驗(yàn)接口的業(yè)務(wù)邏輯 // 一共兩張表,一張是每塊的記錄表(chunck),一張是上傳完成的記錄表(file) // chunck表中的操作 // 1. 根據(jù) identifier 查找數(shù)據(jù)是否存在 // 2. 如果查詢的List的length是 0 說(shuō)明文件不存在,則直接返回沒(méi)有上傳 // 3. 如果不是0,則拿到第一個(gè)數(shù)據(jù),查看文件是否分片 // 4. 如果沒(méi)有分片,那么直接返回已經(jīng)上傳成功,否則返回分片數(shù)據(jù)。
// 分片上傳的邏輯 // 1. 每次上傳完成以后,都把數(shù)據(jù)存到chunck表中 // 2. 當(dāng)所有都上傳完以后,存到文件表file中
到此這篇關(guān)于vue大文件分片上傳之simple-uploader.js的使用的文章就介紹到這了,更多相關(guān)vue大文件分片上傳內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3中WatchEffect高級(jí)偵聽(tīng)器的實(shí)現(xiàn)
本文主要介紹了vue3中WatchEffect高級(jí)偵聽(tīng)器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01vue-cli3.0修改打包后的文件名和文件地址,打包后本地運(yùn)行報(bào)錯(cuò)解決
這篇文章主要介紹了vue-cli3.0修改打包后的文件名和文件地址,打包后本地運(yùn)行報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-0417個(gè)vue常用的數(shù)組方法總結(jié)與實(shí)例演示
這篇文章主要介紹了vue中常用的數(shù)組方法,包括:VUE數(shù)組轉(zhuǎn)換字符串,VUE數(shù)組遍歷,VUE數(shù)組過(guò)濾,VUE數(shù)組查詢,VUE數(shù)組排序等功能,需要的朋友可以參考下2022-12-12Vue打包后訪問(wèn)靜態(tài)資源路徑問(wèn)題
在本篇文章里小編給各位整理的是關(guān)于Vue打包后訪問(wèn)靜態(tài)資源路徑問(wèn)題相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-11-11vue3中安裝并使用CSS預(yù)處理器Sass的方法詳解
Sass是一種CSS預(yù)處理器,它擴(kuò)展了CSS的功能,提供了更高級(jí)的語(yǔ)法和特性,例如變量、嵌套、混合、繼承和顏色功能等,這些特性可以幫助開(kāi)發(fā)者更高效地管理和維護(hù)樣式表,本文介紹vue3中安裝并使用CSS預(yù)處理器Sass的方法,感興趣的朋友一起看看吧2024-01-01vue中選項(xiàng)卡點(diǎn)擊切換且能滑動(dòng)切換功能的實(shí)現(xiàn)代碼
本文通過(guò)實(shí)例代碼給大家介紹了vue中選項(xiàng)卡點(diǎn)擊切換且能滑動(dòng)切換功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下2018-11-11