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-01
vue-cli3.0修改打包后的文件名和文件地址,打包后本地運(yùn)行報(bào)錯(cuò)解決
這篇文章主要介紹了vue-cli3.0修改打包后的文件名和文件地址,打包后本地運(yùn)行報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
17個(gè)vue常用的數(shù)組方法總結(jié)與實(shí)例演示
這篇文章主要介紹了vue中常用的數(shù)組方法,包括:VUE數(shù)組轉(zhuǎn)換字符串,VUE數(shù)組遍歷,VUE數(shù)組過(guò)濾,VUE數(shù)組查詢,VUE數(shù)組排序等功能,需要的朋友可以參考下2022-12-12
Vue打包后訪問(wèn)靜態(tài)資源路徑問(wèn)題
在本篇文章里小編給各位整理的是關(guān)于Vue打包后訪問(wèn)靜態(tài)資源路徑問(wèn)題相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-11-11
vue3中安裝并使用CSS預(yù)處理器Sass的方法詳解
Sass是一種CSS預(yù)處理器,它擴(kuò)展了CSS的功能,提供了更高級(jí)的語(yǔ)法和特性,例如變量、嵌套、混合、繼承和顏色功能等,這些特性可以幫助開(kāi)發(fā)者更高效地管理和維護(hù)樣式表,本文介紹vue3中安裝并使用CSS預(yù)處理器Sass的方法,感興趣的朋友一起看看吧2024-01-01
vue中選項(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

