背景:
說到本人第一次使用spark-md5.js還是差不多一年以前的時候了,當時後臺老大說要搞一個檔案分片上傳的功能。我當時就心想:what?啥是檔案分片上傳,完全沒聽過好嗎?
至於我當時內心那個慌就不多描述了,總之檔案分片上傳需要一個識別檔案的唯一標識,而md5是非常合適的。spark-md5.js就是前端在檔案上傳前在本地計算md5的很可靠的方案
spark-md5.js是外國人寫的,如果英文底子好且想了解更多資訊可以到npm網站了解:www.npmjs.com/package/spa…
使用:
首先要做的當然是在html檔案中引入spark-md5.js咯,根據自己的需求可以引入壓縮版或者開發版
在此之前必須說明,這裡用到了html5提供的FileReader介面,目前實現了這個介面的瀏覽器有FireFox3.6+ 、chrome6+、IE10+,因此如果需要更多的相容的話、抱歉,我目前也沒有找到好的方法
關於FileReader,這裡有一篇高質量的博文可以瞭解一下:blog.csdn.net/jackfrued/a…
這裡提供了兩個方法;一種是用SparkMD5.hashBinary( ) 直接將整個檔案的二進位制碼傳入直接返回檔案的md5、這種方法對於小檔案會比較有優勢——簡單並且速度快。
另一種方法是利用js中File物件的slice( )方法(File.prototype.slice( ))將檔案分片後逐個傳入spark.appendBinary( )方法來計算、最後通過spark.end( )方法輸出結果,很明顯,這種方法對於大型檔案會非常有利——不容易出錯,並且能夠提供計算的進度資訊
我們開始吧,接下來上程式碼:
首先第一種方法:
var running = false; //running用於判斷是否正在計算md5
function doNormalTest( input ) { //這裡假設直接將檔案選擇框的dom引用傳入
if (running) { // 如果正在計算、不允許開始下一次計算
return;
}
var fileReader = new FileReader(), //建立FileReader例項
time;
fileReader.onload = function (e) { //FileReader的load事件,當檔案讀取完畢時觸發
running = false;
// e.target指向上面的fileReader例項
if (file.size != e.target.result.length) { //如果兩者不一致說明讀取出錯
alert("ERROR:Browser reported success but could not read the file until the end.");
} else {
console.log(Finished loading!success!!);
return SparkMD5.hashBinary(e.target.result); //計算md5並返回結果
}
};
fileReader.onerror = function () { //如果讀取檔案出錯,取消讀取狀態並彈框報錯
running = false;
alert("ERROR:FileReader onerror was triggered, maybe the browser aborted due to high memory usage.");
};
running = true;
fileReader.readAsBinaryString( input.files[0] ); //通過fileReader讀取檔案二進位制碼
};
複製程式碼
接下上第二種方法:
function doIncrementalTest( input ) { //這裡假設直接將檔案選擇框的dom引用傳入
if (running) {
return;
}
//這裡需要用到File的slice( )方法,以下是相容寫法
var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
file = input.files[0],
chunkSize = 2097152, // 以每片2MB大小來逐次讀取
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5(), //建立SparkMD5的例項
time,
fileReader = new FileReader();
fileReader.onload = function (e) {
console("Read chunk number (currentChunk + 1) of chunks ");
spark.appendBinary(e.target.result); // append array buffer
currentChunk += 1;
if (currentChunk < chunks) {
loadNext();
} else {
running = false;
console.log("Finished loading!");
return spark.end(); // 完成計算,返回結果
}
};
fileReader.onerror = function () {
running = false;
console.log("something went wrong");
};
function loadNext() {
var start = currentChunk * chunkSize,
end = start + chunkSize >= file.size ? file.size : start + chunkSize;
fileReader.readAsBinaryString(blobSlice.call(file, start, end));
}
running = true;
loadNext();
}
複製程式碼
接下來你只要在input的onchange事件處理程式中呼叫doNormalTest或doIncrementalTest方法,並將input元素的dom節點傳入就可以了
除此之外,作者在他的demo裡面也有使用的詳細例項。如果覺得不明白可以直接通過下面的下載方法下載後看demo
下載:
最後,如果你需要這個工具可以通過npm直接安裝,
npm i spark-md5
或者到作者的github上直接下載: