国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Vue 大文件切片上傳實現指南包會,含【并發(fā)上傳切片,斷點續(xù)傳,服務器合并切片,計算文件MD5,上傳進度顯示,秒傳】等功能

這篇具有很好參考價值的文章主要介紹了Vue 大文件切片上傳實現指南包會,含【并發(fā)上傳切片,斷點續(xù)傳,服務器合并切片,計算文件MD5,上傳進度顯示,秒傳】等功能。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Vue 大文件切片上傳實現指南

背景

????????在Web開發(fā)中,文件上傳是一個常見的功能需求,尤其是當涉及到大文件上傳時,為了提高上傳的穩(wěn)定性和效率,文件切片上傳技術便顯得尤為重要。通過將大文件切分成多個小塊(切片)進行上傳,不僅可以有效減少單次上傳的數據量,降低網絡波動對上傳過程的影響,還能實現如斷點續(xù)傳、秒傳等高級功能。本文將以Vue為框架,配合 Axios 進行 HTTP 請求,詳細介紹如何實現一個支持文件切片上傳的功能。

前端準備工作

????????在開始編碼之前,請確保你的項目中已經安裝了 axiosspark-md5 兩個庫。axios 用于發(fā)起網絡請求,spark-md5 用于計算文件的 MD5 值,從而支持秒傳和斷點續(xù)傳功能。

前端需要實現的功能

  1. 文件選擇和限制:

    通過<input type="file" @change="handleFileChange" accept="video/*" />實現了文件的選擇,同時限制了用戶只能選擇視頻文件進行上傳。

  2. 計算文件的MD5值

    computeFileHash方法中,利用SparkMD5庫計算用戶選中文件的MD5值。這一步是為了之后能夠校驗文件的完整性和唯一性。

  3. 校驗文件是否需要上傳

    checkFile方法中,通過向服務器查詢文件的MD5值,判斷該文件是否已經上傳過,以此實現秒傳功能,避免重復上傳相同文件。

  4. 文件切片

    sliceFileAndUpload方法中,將大文件切割成多個小片段(切片),這樣做的目的是為了支持大文件的分塊上傳,提高上傳效率,同時也便于出錯時重新上傳單個切片而不是整個文件。

  5. 并發(fā)上傳切片

    通過processPooluploadChunk方法實現切片的并發(fā)上傳,限制了最大并發(fā)數(MAX_REQUEST),以免過多并發(fā)請求壓崩服務器。

  6. 上傳進度反饋

    通過uploadProgress數據和模板中的進度顯示,用戶可以實時看到文件上傳的進度。

  7. 服務器通知合并切片

    在所有切片上傳完成后,通過notifyServerToMerge方法向服務器發(fā)送通知,請求服務器端進行切片的合并,以重建原始文件。

后端需要支持的API接口

為了支持前端的大文件上傳和處理邏輯,后端需要提供以下API接口:

  1. 文件校驗API
  • 功能:檢查文件的完整性和上傳狀態(tài)。這通常通過文件的唯一標識(如MD5哈希值)來實現。
  • 輸入參數:文件唯一標識(如MD5哈希值)。
  • 返回值:告知客戶端該文件是否已經存在,如果存在,是否完整。如果文件已經存在且不完整,則返回已上傳的切片信息。
  1. 切片上傳API
  • 功能:接收文件的單個切片,并保存到服務器的臨時存儲位置。
  • 輸入參數:文件的唯一標識,切片內容,切片的序號。
  • 返回值:確認切片上傳成功或失敗的狀態(tài)。
  1. 切片合并API
  • 功能:將所有上傳的切片合并成一個完整的文件。
  • 輸入參數:文件的唯一標識,可能還包括文件名、總切片數等信息。
  • 返回值:合并操作的成功或失敗狀態(tài),以及最終文件的訪問URL(可選)。
  1. 上傳進度查詢API
  • 功能:查詢文件上傳的進度,這對于恢復上傳和提供用戶反饋非常有用。
  • 輸入參數:文件的唯一標識。
  • 返回值:已上傳的切片列表或上傳進度百分比。

這些API合起來支持了一個分塊上傳文件的完整流程,包括文件的校驗、切片的上傳、切片的合并,以及上傳進度查詢。這個流程可以有效地處理大文件上傳,減少網絡傳輸的負擔,提高上傳的可靠性,并允許上傳過程中的暫停和恢復。

執(zhí)行流程

????????一開始用戶通過界面選擇一個文件進行上傳,進行文件選擇,用戶通過文件選擇框懸著一個大文件,比如視頻文件,觸發(fā)handleFileChange方法,然后再計算這個大文件的MD5,使用computeFileHash方法計算選中文件的MD5哈希值,計算完成后檢查文件是否需要上傳,向服務器發(fā)起請求,根據文件的MD5哈希值執(zhí)行checkFile方法檢查文件是否已經存在,如果文件已經存在通知用戶秒傳功能并將上傳進度設為100%,如果文件需要上傳,則使用sliceFileAndUpload方法將文件切成很多個小塊,每個切片及其索引都被添加到requestPool請求池中,從requestPool中并發(fā)上傳切片processPool方法,對每個切片調用uploadChunk方法進行實際上傳,通過MAX_REQUEST控制并發(fā)上傳的數量,沒上傳一個切片,uploadChunksCount增加,并更新上傳進度。所有切片上傳完成后,通知服務器合并這些切片notifyServerToMerge,當服務器成功合并所有切片成原始后,整個切片上傳流程完成。

實現步驟

步驟一:用戶選擇文件

????????用戶通過 <input type="file"> 選擇文件后,handleFileChange 事件被觸發(fā)。在這個事件處理函數中,我們首先獲取到用戶選擇的文件,然后計算文件的 MD5 值,以此作為文件的唯一標識。這一步是實現斷點續(xù)傳秒傳功能的關鍵。

<template>
  <div>
    <!-- 文件選擇框,僅接受視頻文件 -->
    <input type="file" @change="handleFileChange" accept="video/*" />
    <!-- 上傳按鈕 -->
    <button @click="handleUpload">Upload</button>
    <!-- 上傳進度顯示 -->
    <div v-if="uploadProgress > 0">
      Upload Progress: {{ uploadProgress }}%
    </div>
  </div>
</template>

步驟二:計算文件 MD5

????????使用 spark-md5 庫計算文件的 MD5 值。通過FileReader API 讀取文件內容,然后計算其 MD5 值。這個過程可能會花費一些時間,因此使用 Promise 來異步處理。

async computeFileHash(file) {
  const spark = new SparkMD5.ArrayBuffer();
  const fileReader = new FileReader();
  return new Promise((resolve) => {
    fileReader.onload = (e) => {
      spark.append(e.target.result);
      const hash = spark.end();
      resolve(hash);
    };
    fileReader.readAsArrayBuffer(file);
  });
}

步驟三:檢查文件狀態(tài),檢查文件是否已經上傳還是部分上傳

????????在上傳文件之前,先向服務器發(fā)送請求,檢查這個文件是否已經部分或全部上傳過。這一步是實現斷點續(xù)傳的關鍵。服務器根據文件的 MD5 值返回已上傳的切片信息或表示文件完全上傳的狀態(tài)。

 // 向服務器查詢文件是否已經部分或完全上傳
async checkFile(fileHash) {  
 <---  此處應替換為你的接口調用代碼  --->
 // 假設接口返回 { shouldUpload: boolean, uploadedChunks: Array<number> }
  return { shouldUpload: true, uploadedChunks: [] };
},

步驟四:切片并準備上傳

????????根據服務器返回的信息,如果文件未完全上傳,我們將文件分割成多個切片。然后根據已上傳的切片信息,跳過那些已經上傳的切片,僅上傳剩余的切片。
????????切片并準備上傳在sliceFileAndUpload方法中實現。這個方法首先計算了整個文件應該被分割成多少切片(基于設定的切片大?。?,然后根據服務器返回的已上傳切片信息(uploadedChunks),它會跳過這些已經上傳的切片,只將剩余的切片添加到請求池(requestPool)中準備上傳。

 // 切片并準備上傳
sliceFileAndUpload(fileHash, uploadedChunks) {
    const chunkSize = 10 * 1024 * 1024; // 切片大小,這里是10MB
    this.chunkCount = Math.ceil(this.selectedFile.size / chunkSize); // 計算總切片數
    this.uploadProgress = 0; // 重置上傳進度
    for (let i = 0; i < this.chunkCount; i++) {
      if (uploadedChunks.includes(i)) continue; // 跳過已上傳的切片
      const chunk = this.selectedFile.slice(i * chunkSize, (i + 1) * chunkSize); // 獲取切片
      this.requestPool.push({ chunk, index: i }); // 加入請求池
    }
    this.processPool(fileHash); // 開始處理請求池
  },

上面這段代碼中,uploadedChunks參數是一個數組,包含了所有已上傳切片的索引。通過檢查當前切片的索引是否包含在這個數組中,代碼決定是否跳過當前切片的上傳。如果索引不在uploadedChunks中,這意味著該切片還沒有被上傳,因此需要將其添加到requestPool中等待上傳。這樣,只有那些未上傳的切片會被實際上傳,從而實現了斷點續(xù)傳的功能。processPool進行并發(fā)切片上傳

步驟五:并發(fā)上傳切片

????????為了提高上傳效率,我們使用并發(fā)上傳的方式。設置最大并發(fā)數,控制同時上傳的切片數量。通過逐一上傳切片,并監(jiān)聽每個上傳請求的完成,從而動態(tài)調整并發(fā)請求。
????????并發(fā)上傳切片的邏輯主要在processPool方法中實現。這個方法負責管理并發(fā)請求,確保同時只有一定數量的上傳請求在處理中。這通過一個簡單的請求池(requestPool)和控制最大并發(fā)數量(MAX_REQUEST)來實現。

// 處理請求池中的切片上傳
processPool(fileHash) {
  while (this.requestPool.length > 0 && this.MAX_REQUEST > 0) {
    const { chunk, index } = this.requestPool.shift(); // 取出一個待上傳的切片
    this.uploadChunk(chunk, fileHash, index) // 上傳切片
      .then(() => {
        this.uploadedChunksCount++; // 更新已上傳切片數量
        this.uploadProgress = ((this.uploadedChunksCount / this.chunkCount) * 100).toFixed(2); // 更新上傳進度
        if (this.requestPool.length > 0) {
          this.processPool(fileHash); // 繼續(xù)處理請求池
        } else if (this.uploadedChunksCount === this.chunkCount) {
          // 所有切片都已上傳,通知服務器合并
          this.notifyServerToMerge(fileHash);
        }
      })
      .finally(() => {
        this.MAX_REQUEST++; // 釋放一個請求槽
      });
    this.MAX_REQUEST--; // 占用一個請求槽
  }
},

????????在這個方法中,while循環(huán)檢查請求池中是否還有待處理的切片,并且當前活躍的請求數量是否小于允許的最大并發(fā)數量MAX_REQUEST。如果這兩個條件都滿足,它會從請求池中取出一個切片,并調用uploadChunk方法來上傳它,同時減少MAX_REQUEST的值來反映一個新的請求已經開始。
????????當一個切片上傳完成后,then回調函數會增加已上傳切片的計數并更新上傳進度。如果請求池中還有待上傳的切片,它會遞歸調用processPool來處理下一個切片。一旦所有切片都上傳完成,它會調用notifyServerToMerge來通知服務器所有切片已經上傳完畢,可以合并成一個完整的文件。通過這種方式,代碼能夠在保持最大并發(fā)限制的同時,高效地處理切片的上傳。

步驟六:服務器合并切片

????????所有切片上傳完成后,客戶端向服務器發(fā)送一個合并切片的請求。服務器接收到請求后,將所有切片合并成原始文件,并返回合并結果。

// 通知服務器合并切片
notifyServerToMerge(fileHash) {
  // 通知服務器合并切片,應替換為真實的合并API調用
  console.log(`通知服務器將文件與哈希合并: ${fileHash}`);
},

????????一個API調用,向服務器發(fā)送一個請求來觸發(fā)合并已上傳切片的操作。這個請求通常會攜帶一些必要的信息,比如文件的唯一標識(在這個例子中是fileHash),以及可能還有其他諸如文件名、文件大小、切片數量等信息,這些信息取決于服務器端合并切片的具體要求。
????????服務器收到合并請求后,會根據提供的信息找到所有相關的切片,按正確的順序將它們合并成一個完整的文件,并將該文件存儲在服務器上的適當位置。完成這個過程后,服務器可能還會向客戶端發(fā)送一個響應,通知合并操作的結果(成功或失?。?,以及可能的后續(xù)步驟或需要的信息。
????????通過上述步驟,實現了一個高效穩(wěn)定的大文件上傳功能,極大提升了用戶體驗。

全部代碼

<template>
  <div>
    <!-- 文件選擇框,僅接受視頻文件 -->
    <input type="file" @change="handleFileChange" accept="video/*" />
    <!-- 上傳按鈕 -->
    <button @click="handleUpload">Upload</button>
    <!-- 上傳進度顯示 -->
    <div v-if="uploadProgress > 0">
      Upload Progress: {{ uploadProgress }}%
    </div>
  </div>
</template>

<script>
import axios from "axios";
import SparkMD5 from "spark-md5"; // 引入SparkMD5用于計算文件的MD5值

export default {
  data() {
    return {
      selectedFile: null, // 用戶選擇的文件
      uploadProgress: 0, // 上傳進度
      requestPool: [], // 請求池,存儲待上傳的切片信息
      MAX_REQUEST: 6, // 最大并發(fā)請求數量
      chunkCount: 0, // 文件切片總數
      uploadedChunksCount: 0, // 已上傳的切片數量
    };
  },
  methods: {
    // 處理文件選擇事件
    async handleFileChange(event) {
      this.selectedFile = event.target.files[0];
      if (!this.selectedFile) return; // 未選擇文件則返回
      // 可以在這里添加文件格式校驗
      const fileHash = await this.computeFileHash(this.selectedFile); // 計算文件hash
      const { shouldUpload, uploadedChunks } = await this.checkFile(fileHash); // 檢查文件是否需要上傳
      if (!shouldUpload) {
        alert("文件已存在,秒傳成功!");
        this.uploadProgress = 100; // 直接設置進度為100%
        return;
      }
      this.sliceFileAndUpload(fileHash, uploadedChunks); // 切片并上傳
    },
    // 計算文件的MD5
    computeFileHash(file) {
      return new Promise((resolve) => {
        const spark = new SparkMD5.ArrayBuffer();
        const fileReader = new FileReader();
        fileReader.onload = (e) => {
          spark.append(e.target.result);
          const hash = spark.end();
          resolve(hash); // 返回計算得到的hash值
        };
        fileReader.readAsArrayBuffer(file);
      });
    },
    // 檢查文件是否已經上傳過
    async checkFile(fileHash) {
      // 應替換為真實的API調用來檢查文件狀態(tài)
      return { shouldUpload: true, uploadedChunks: [] }; // 模擬返回值
    },
    // 切片并準備上傳
    sliceFileAndUpload(fileHash, uploadedChunks) {
      const chunkSize = 10 * 1024 * 1024; // 切片大小,這里是10MB
      this.chunkCount = Math.ceil(this.selectedFile.size / chunkSize); // 計算總切片數
      this.uploadProgress = 0; // 重置上傳進度
      for (let i = 0; i < this.chunkCount; i++) {
        if (uploadedChunks.includes(i)) continue; // 跳過已上傳的切片
        const chunk = this.selectedFile.slice(i * chunkSize, (i + 1) * chunkSize); // 獲取切片
        this.requestPool.push({ chunk, index: i }); // 加入請求池
      }
      this.processPool(fileHash); // 開始處理請求池
    },
    // 處理請求池中的切片上傳
    processPool(fileHash) {
      while (this.requestPool.length > 0 && this.MAX_REQUEST > 0) {
        const { chunk, index } = this.requestPool.shift(); // 取出一個待上傳的切片
        this.uploadChunk(chunk, fileHash, index) // 上傳切片
          .then(() => {
            this.uploadedChunksCount++; // 更新已上傳切片數量
            this.uploadProgress = ((this.uploadedChunksCount / this.chunkCount) * 100).toFixed(2); // 更新上傳進度
            if (this.requestPool.length > 0) {
              this.processPool(fileHash); // 繼續(xù)處理請求池
            } else if (this.uploadedChunksCount === this.chunkCount) {
              // 所有切片都已上傳,通知服務器合并
              this.notifyServerToMerge(fileHash);
            }
          })
          .finally(() => {
            this.MAX_REQUEST++; // 釋放一個請求槽
          });
        this.MAX_REQUEST--; // 占用一個請求槽
      }
    },
    // 上傳單個切片
    async uploadChunk(chunk, fileHash, index) {
      const formData = new FormData();
      formData.append("chunk", chunk);
      formData.append("hash", fileHash);
      formData.append("index", index);
      // 替換為真實的上傳URL,并根據需要實現onUploadProgress
      await axios.post("上傳URL", formData);
    },
    // 通知服務器合并切片
    notifyServerToMerge(fileHash) {
      // 通知服務器合并切片,應替換為真實的合并API調用
      console.log(`通知服務器將文件與哈希合并: ${fileHash}`);
    },
  },
};
</script>

效果:
vue大文件切片上傳,Vue,JavaScript,vue.js,服務器,前端,javascript文章來源地址http://www.zghlxwxcb.cn/news/detail-860911.html

到了這里,關于Vue 大文件切片上傳實現指南包會,含【并發(fā)上傳切片,斷點續(xù)傳,服務器合并切片,計算文件MD5,上傳進度顯示,秒傳】等功能的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【萬字長文】Vue+SpringBoot實現大文件秒傳、斷點續(xù)傳和分片上傳完整教程(提供Gitee源碼)

    前言:最近在實際項目中碰到一個需求,客戶可能會上傳比較大的文件,如果采用傳統(tǒng)的文件上傳方案可能會存在服務器壓力大、資源浪費甚至內存溢出的一些安全風險,所以為了解決一系列問題,需要采用新的技術方案來實現大文件的上傳;空閑的時候參考了網上的一些相

    2024年02月12日
    瀏覽(24)
  • vue+ts大文件切片上傳

    vue+ts大文件切片上傳

    別看文字了,看代碼注釋吧§(* ̄▽ ̄*)§ 1. src 下 的.vue 文件?src/APP.vue 2. src下文件夾,與上方??代碼在同一目錄?src/utils/index.ts 3.效果圖 ? 非常簡單(。?ω?。)?

    2024年01月23日
    瀏覽(31)
  • vue 大文件視頻切片上傳處理方法

    前端上傳大文件、視頻的時候會出現超時、過大、很慢等情況,為了解決這一問題,跟后端配合做了一個切片的功能。 我這個切片功能是基于 minion 的,后端會把文件放在minion服務器上。具體看后端怎么做 1、在項目的 util(這個文件夾是自己創(chuàng)建的,如果項目里沒有可以自行

    2024年02月13日
    瀏覽(19)
  • 前端--文件上傳--文件切片--利用FileReader()中的readAsDataURL()做縮略圖--多文件上傳--formData--切片上傳實現

    前端--文件上傳--文件切片--利用FileReader()中的readAsDataURL()做縮略圖--多文件上傳--formData--切片上傳實現

    可以把File 類型 轉換為 Blob 類型,因為 File 是Blob的子類 Blob是不可修改也是無法讀取里面的內容的。但是Filereader就提供了讀取Blob里面內容的方法。 1.做縮略圖用readAsDataURL 給圖片顯示一下 可以利用切片來實現上傳半張圖片的效果 2. 也可以做文本預覽(利用readAsText)方式和上

    2023年04月20日
    瀏覽(31)
  • 基于vue-simple-uploader封裝文件分片上傳、秒傳及斷點續(xù)傳的全局上傳

    基于vue-simple-uploader封裝文件分片上傳、秒傳及斷點續(xù)傳的全局上傳

    1. 前言 文件上傳 小文件(圖片、文檔、視頻)上傳可以直接使用很多ui框架封裝的上傳組件,或者自己寫一個input 上傳,利用FormData 對象提交文件數據,后端使用spring提供的MultipartFile進行文件的接收,然后寫入即可。但是對于比較大的文件,比如上傳2G左右的文件(http上傳

    2024年02月06日
    瀏覽(22)
  • Minio大文件分片上傳、斷點續(xù)傳實現

    Minio大文件分片上傳、斷點續(xù)傳實現

    使用minio api實現分片上傳及斷點續(xù)傳功能。 前端準備:獲取大文件的MD5值,將文件分片,5M為一分片,排好順序,并按順序命名(1,2,3這種后面比較好合并) 在上傳分片階段,前端有上傳進度條 1、檢驗文件MD5值 1.1 redis中查看MD5是否存在 1.2 判斷臨時文件夾是否存在 boolean d

    2024年02月09日
    瀏覽(27)
  • springboot整合vue2-uploader文件分片上傳、秒傳、斷點續(xù)傳

    springboot整合vue2-uploader文件分片上傳、秒傳、斷點續(xù)傳

    vue-simple-uploader 是基于 simple-uploader.js 封裝的vue上傳插件。它的優(yōu)點包括且不限于以下幾種: 支持文件、多文件、文件夾上傳;支持拖拽文件、文件夾上傳 可暫停、繼續(xù)上傳 錯誤處理 支持“秒傳”,通過文件判斷服務端是否已存在從而實現“秒傳” 分片上傳 支持進度、預估

    2024年02月06日
    瀏覽(35)
  • minio&前后端分離上傳視頻/上傳大文件——前后端分離斷點續(xù)傳&minio分片上傳實現

    minio&前后端分離上傳視頻/上傳大文件——前后端分離斷點續(xù)傳&minio分片上傳實現

    ????????分布式文件系統(tǒng)-minio: 第一章:分布式文件系統(tǒng)介紹與minio介紹與使用(附minio java client 使用) 第二章:minio前后端分離上傳視頻/上傳大文件——前后端分離斷點續(xù)傳minio分片上傳實現 斷點續(xù)傳指的是在下載或上傳時,將下載或上傳任務(一個文件或一個壓縮包

    2024年02月03日
    瀏覽(44)
  • Spring Boot + MinIO 實現文件切片極速上傳技術

    Spring Boot + MinIO 實現文件切片極速上傳技術

    ??歡迎來到SpringBoot框架學習專欄~ ☆* o(≧▽≦)o *☆嗨~我是IT·陳寒?? ?博客主頁:IT·陳寒的博客 ??該系列文章專欄:SpringBoot ??其他專欄:Java學習路線 Java面試技巧 Java實戰(zhàn)項目 AIGC人工智能 數據結構學習 ??文章作者技術和水平有限,如果文中出現錯誤,希望大家能指

    2024年02月04日
    瀏覽(22)
  • 【SpringBoot整合系列】SpringBoot 實現大文件分片上傳、斷點續(xù)傳及秒傳

    【SpringBoot整合系列】SpringBoot 實現大文件分片上傳、斷點續(xù)傳及秒傳

    小文件(圖片、文檔、視頻)上傳可以直接使用很多ui框架封裝的上傳組件,或者自己寫一個input 上傳,利用FormData 對象提交文件數據,后端使用spring提供的MultipartFile進行文件的接收,然后寫入即可。 但是對于比較大的文件,比如上傳2G左右的文件(http上傳),就需要將文件

    2024年04月16日
    瀏覽(37)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包