亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

一文帶你徹底搞懂JS大文件分片上傳的實現(xiàn)

 更新時間:2023年05月31日 10:44:54   作者:落葉飄  
這篇文章主要為大家詳細介紹了前端JavaScript是如何實現(xiàn)大文件分片上傳的,文中的示例代碼講解詳細,具有一定的學習價值,需要的可以參考一下

學習AbortController

AbortController 接口表示一個控制器對象,允許你根據(jù)需要中止一個或多個 Web 請求。

可以通過這個來實現(xiàn)取消或者中斷請求的功能。

axios.abort();底層實現(xiàn)就是這個。

認識了

fse = require('fs-extra')

概述

實現(xiàn)文件分片上傳的原理就是通過將文件的ArrayBlob形式,通過file(blob)的方法slice,來實現(xiàn)將文件拆成幾個部分,然后排上順序傳到服務端,最后傳完了調(diào)用服務端的merge合并接口,服務端將文件合并。

服務端實現(xiàn)原理,上傳前創(chuàng)建文件夾,命名注意了,可以參考給到的代碼。然后將獲得的文件通過fse的寫入方法,寫入到我們創(chuàng)建的文件夾中,并且有相應的排序。最后我們通過合并方法將文件合并到一個文件。

詳細學習

Client端

getChunkListAndFileMd5函數(shù)

這個函數(shù)用來創(chuàng)建分片數(shù)組,以及生成Hash簽名。

創(chuàng)建分片列表數(shù)組,我們使用的方法是file.prototype.slice當然這里我們?yōu)榱私鉀Q兼容性問題,我們使用的代碼是:

export function getBlobSlice() {
    return (File.prototype.slice ||
        File.prototype.mozSlice ||
        File.prototype.webkitSlice);
}

創(chuàng)建分片:getBlobSlice.call(file,start,end)。這里start、end分別是起始位置和終點位置,我們確認好分片大小就可以計算start和end。

好,那么我們開始了,我們定義size是 5M 代碼如下

const DEFAULT_CHUNK_SIZE = 5 * 1024 * 1024;

我們定義一個對象保存默認配置:

const DEFAULT_OPTIONS = {
    chunkSize: DEFAULT_CHUNK_SIZE,
};

我們來定義分片的編號,初始值肯定是 0。我們定義chunkSize來保存我們上邊定義的常量分片大小。

let currentChunk = 0;
const chunkSize = this.fileUploaderClientOptions.chunkSize; 

接下來我們需要計算需要多少個分片,很簡單:文件總的大小/每個分片的大小,最終結果可能是個小數(shù),但是為了保證分片的完整肯定是向上取整。

const chunks = Math.ceil(file.size / chunkSize);

定義一個函數(shù)來加載分片,代碼如下:

function loadNextChunk() {
    const start = currentChunk * chunkSize;
    const end = start + chunkSize >= file.size ? file.size : start + chunkSize;
    const chunk = blobSlice.call(file, start, end);
    chunkList.push(chunk);
    fileReader.readAsArrayBuffer(chunk);
}

拆解這個函數(shù):

1.計算start位置,這個不難理解。

2.計算end位置,這里需要判斷一下,主要是針對兩種情況:

文件尺寸很小,小于分片大小,直接取文件的尺寸。

最后一個切片,大小可能沒有切片尺寸大,我們直接取文件大小的位置。

3.調(diào)用我們上邊說的函數(shù)來實現(xiàn)分片,并且獲取當前的分片。

4.將當前的分片push到我們的數(shù)組中。

5.調(diào)用fileReader.readAsArrayBuffer方法來讀取分片。(其實當前的分片是一個blob實例,我們通過這個方法可以讀取到里邊的內(nèi)容)。
接下來我們來看看fileReader是怎么回事。

認識FileReader

不懂fileReader的可以先看看文檔,了解下里邊的方法。

FileReader 對象允許 Web 應用程序異步讀取存儲在用戶計算機上的文件(或原始數(shù)據(jù)緩沖區(qū))的內(nèi)容,使用 File 或 Blob 對象指定要讀取的文件或數(shù)據(jù)。
其中 File 對象可以是

  • 來自用戶在一個 元素上選擇文件后返回的FileList對象
  • 也可以來自拖放操作生成的 DataTransfer對象,
  • 還可以是來自在一個HTMLCanvasElement上執(zhí)行mozGetAsFile()方法后返回結果。

FileReader可以在Web Worker中使用。 (重要,可以很大成都解決性能問題)

這里因為用到了FileReader的方法,所以重點講講這個對象的方法。

  • FileReader.abort(); 中止讀取操作。
  • FileReader.readAsArrayBuffer(); 開始讀取指定的 Blob中的內(nèi)容,一旦完成,result 屬性中保存的將是被讀取文件的 ArrayBuffer數(shù)據(jù)對象。
  • FileReader.readAsDataURL(); 開始讀取指定的Blob中的內(nèi)容。一旦完成,result屬性中將包含一個data: URL 格式的 Base64 字符串以表示所讀取文件的內(nèi)容。
  • FileReader.readAsText();開始讀取指定的Blob中的內(nèi)容。一旦完成,result屬性中將包含一個字符串以表示所讀取的文件內(nèi)容。

我們目前需要讀取分片的內(nèi)容,并且需要ArrayBuffer的格式,所以我們創(chuàng)建一個FileReader對象實例,并且使用readAsArrayBuffer方法來讀取文件,通過onload事件來監(jiān)聽,獲取最終結果。代碼如下:

const fileReader = new FileReader();
fileReader.onload = function (e) {
    // 我們讀取到的結果是 e.target.result
}
fileReader.onerror = function (e) {
    // 這里表示讀取失敗
}

上邊loadNextChunk函數(shù)中調(diào)用了這個方法。

fileReader.readAsArrayBuffer(chunk);

使用md5來實現(xiàn)簽名

用到了 spark-md5 這個三方庫。主要使用的方法是生成md5的編碼。

npm install --save spark-md5

npmjs中的spark-md5

github

這個就是一個處理分片的一個庫。給出了方法:

const spark = new SparkMD5.ArrayBuffer();

將分片 v 添加到對象中

spark.append(v)

最終結果返回

const result = spark.end()

uploadFile函數(shù)

這個函數(shù)用來上傳文件的函數(shù)。

首先我們要獲取上邊我們函數(shù)得到的值 md5、chunkList。

const { md5, chunkList } = yield this.getChunkListAndFileMd5(file);

上傳文件前,需要調(diào)用接口來初始化文件分片上傳,這里我們其實就是調(diào)用初始化文件分片上傳的接口requestOptions.initFilePartUploadFunc。

yield requestOptions.initFilePartUploadFunc();

這個接口在后端的實現(xiàn)其實就是創(chuàng)建好一個文件夾用來保存分片,這里就不多說了,之后在學習Server代碼的時候我們細講。
接下來就是開始上傳我們的分片了,上傳方法requestOptions.uploadPartFileFunc:

for (let index = 0; index < chunkList.length; index++) {
    try {
        yield requestOptions.uploadPartFileFunc(chunkList[index], index);
    }
    catch (e) {
        console.warn(`${index} part upload failed`);
        retryList.push(index);
    }
}

注意了:我們不能保證全部順利上傳,如果中間出現(xiàn)問題中斷了上傳等問題,我們?nèi)绾翁幚恚?/p>

這里我們使用retryTimes來獲取需要重新上傳的列表。

for (let retry = 0; retry < requestOptions.retryTimes; retry++) {
    if (retryList.length > 0) {
        console.log(`retry start, times: ${retry}`);
        for (let a = 0; a < retryList.length; a++) {
            const blobIndex = retryList[a];
            try {
                yield requestOptions.uploadPartFileFunc(chunkList[blobIndex], blobIndex);
                retryList.splice(a, 1);
            }
            catch (e) {
                console.warn(`${blobIndex} part retry upload failed, times: ${retry}`);
            }
        }
    }
}

最后我們調(diào)用上傳結束的接口requestOptions.finishFilePartUploadFunc(md5),其實這個接口主要是通知服務端,分片都上傳完了,服務端可以進行文件合并了,最終將分片合并成一個文件。

if (retryList.length === 0) {
    return yield requestOptions.finishFilePartUploadFunc(md5);
}
else {
    throw Error(`upload failed, some chunks upload failed: ${JSON.stringify(retryList)}`);
}

至此,客戶端的操作完畢!

完整代碼

以上就是一文帶你徹底搞懂JS大文件分片上傳的實現(xiàn)的詳細內(nèi)容,更多關于JS大文件分片上傳的資料請關注腳本之家其它相關文章!

相關文章

  • Javascript 實現(xiàn)放大鏡效果實例詳解

    Javascript 實現(xiàn)放大鏡效果實例詳解

    這篇文章主要介紹了Javascript 實現(xiàn)放大鏡效果實例詳解的相關資料,這里附有實現(xiàn)實例代碼,具有參考價值,需要的朋友可以參考下
    2016-12-12
  • JS組件Bootstrap Table布局詳解

    JS組件Bootstrap Table布局詳解

    這篇文章主要為大家詳細介紹了JS組件Bootstrap Table布局,用戶體驗比較好,更好兼容各種客戶端,需要了解更多bootstrap table的朋友可以參考下
    2016-05-05
  • JS事件流與事件處理程序實例分析

    JS事件流與事件處理程序實例分析

    這篇文章主要介紹了JS事件流與事件處理程序,結合實例形式分析了事件流與事件處理程序相關概念、原理、用法及操作注意事項,需要的朋友可以參考下
    2019-08-08
  • 關于js中removeEventListener取消事件監(jiān)聽的坑

    關于js中removeEventListener取消事件監(jiān)聽的坑

    許多入前端不久的人都會遇到removeEventListener無法清除監(jiān)聽的情況,下面這篇文章主要給大家介紹了關于js中removeEventListener取消事件監(jiān)聽的坑,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • 重學 JS:為啥 await 不能用在 forEach 中詳解

    重學 JS:為啥 await 不能用在 forEach 中詳解

    這篇文章主要介紹了重學 JS:為啥 await 不能用在 forEach 中,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • 淺談webpack 自動刷新與解析

    淺談webpack 自動刷新與解析

    這篇文章主要介紹了淺談webpack 自動刷新與解析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • 解決微信授權成功后點擊按返回鍵出現(xiàn)空白頁和報錯的問題

    解決微信授權成功后點擊按返回鍵出現(xiàn)空白頁和報錯的問題

    這篇文章主要介紹了解決微信授權成功后點擊按返回鍵出現(xiàn)空白頁和報錯的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • 深入淺析Node環(huán)境和瀏覽器的區(qū)別

    深入淺析Node環(huán)境和瀏覽器的區(qū)別

    最近有朋友問我node環(huán)境和瀏覽器的區(qū)別這一問題,今天小編就抽空給大家介紹下Node環(huán)境和瀏覽器的區(qū)別,感興趣的朋友一起看看吧
    2018-08-08
  • DOM操作原生js 的bug,使用jQuery 可以消除的解決方法

    DOM操作原生js 的bug,使用jQuery 可以消除的解決方法

    下面小編就為大家?guī)硪黄狣OM操作原生js 的bug,使用jQuery 可以消除的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • jquery實現(xiàn)的圖片點擊滾動效果

    jquery實現(xiàn)的圖片點擊滾動效果

    這篇文章主要介紹了jquery實現(xiàn)的圖片點擊滾動效果,需要的朋友可以參考下
    2014-04-04

最新評論