JavaScript 檔案上傳

yuzhihui發表於2023-01-29

一、普通檔案上傳

JavaScript 可以使用表單提交來實現檔案上傳。首先,在 HTML 中建立一個檔案輸入框:

<input type="file" id="fileInput">

然後,在 JavaScript 中獲取檔案輸入框的引用,並在其上設定事件監聽器,如下所示:

var fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function () {
  // 在這裡處理選擇的檔案
});

在事件監聽器中,可以使用 fileInput.files[0] 屬性獲取選擇的檔案,然後對檔案進行處理。

接下來可以使用 XMLHttpRequestfetch API 來上傳檔案。

使用 XMLHttpRequest

var file = fileInput.files[0];
var formData = new FormData();
formData.append('file', file);

var xhr = new XMLHttpRequest();
xhr.open('POST', 'url', true);
xhr.onload = function () {
  if (xhr.status === 200) {
    console.log('upload success');
  }
};
xhr.send(formData);

使用 fetch

var file = fileInput.files[0];
var formData = new FormData();
formData.append('file', file);

fetch('url', {
  method: 'POST',
  body: formData
}).then(response => {
  if (response.ok) {
    console.log('upload success');
  }
});

另外還可以使用第三方庫如 axios 來實現檔案上傳,具體實現方法可以參考相關檔案。

二、大檔案上傳

在上傳大檔案時,通常採用分塊上傳的方式。將大檔案分成若干個塊,每塊一個 HTTP 請求上傳。

實現大檔案上傳的步驟如下:

  1. 使用者選擇檔案。
  2. 將檔案分成若干塊。
  3. 對於每一塊,向伺服器傳送 HTTP 請求上傳。
  4. 伺服器接收到檔案塊後,將其儲存在伺服器上。
  5. 在所有塊上傳完成後,伺服器將所有塊合併成一個完整的檔案。

JavaScript 可以使用 File API(File 和 Blob 物件)來實現檔案的讀取和上傳。

下面是一個使用 JavaScript 實現大檔案上傳的簡單例項,使用分塊上傳的方法。

<input type="file" id="file-input">

 

// 上傳檔案塊
function uploadChunk(file, start, end, chunk) {
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload', true);
    xhr.setRequestHeader('Content-Type', 'application/octet-stream');
    xhr.setRequestHeader('Content-Range', 'bytes ' + start + '-' + end + '/' + file.size);
    xhr.send(chunk);
}

// 上傳檔案
function uploadFile(file) {
    var chunkSize = 1 * 1024 * 1024; // 分塊大小為1MB
    var chunks = Math.ceil(file.size / chunkSize); // 計算分塊數
    var currentChunk = 0; // 當前分塊
    var start, end;
    while (currentChunk < chunks) {
        start = currentChunk * chunkSize;
        end = start + chunkSize >= file.size ? file.size : start + chunkSize;
        var chunk = file.slice(start, end);
        uploadChunk(file, start, end, chunk);
        currentChunk++;
    }
}

// 監聽檔案選擇事件
document.getElementById('file-input').addEventListener('change', function(e) {
    var file = e.target.files[0];
    if (file) {
        uploadFile(file);
    }
});

在這個例項中,我們使用了 XMLHttpRequest 物件上傳檔案,並設定了 Content-Type 和 Content-Range 訊息頭。Content-Type 訊息頭表示上傳的資料型別是二進位制資料,Content-Range 訊息頭表示上傳的檔案塊的範圍。

在這個示例中,我們將檔案分成若干塊,每塊大小為 1MB。我們使用 File API 中的 slice 方法擷取檔案塊,並使用 XMLHttpRequest 將檔案塊上傳到伺服器。

注意,這只是一個簡單的例項,程式碼僅供參考,在實際應用中還需要考在考慮以下幾點:

  • 如果伺服器端支援斷點續傳,可以在伺服器端記錄已經上傳的檔案塊,避免重複上傳。
  • 需要考慮如何處理上傳失敗的檔案塊,是否需要重試。
  • 在上傳過程中需要提供進度條,讓使用者瞭解上傳進度。
  • 在上傳完成後需要有反饋,告知使用者上傳是否成功。
  • 伺服器端如何處理上傳的檔案塊,將其合併成一個完整的檔案。
  • 伺服器端儲存空間的問題。可以使用分散式檔案系統(如 HDFS)或雲端儲存(如 Amazon S3)來儲存上傳的檔案。
  • 檔案塊上傳順序、檔案塊校驗、斷點續傳等問題。

透過分塊上傳的方式,我們可以將大檔案分成若干塊上傳,避免一次性上傳大檔案造成的超時或者記憶體不足的問題,同時也方便實現斷點續傳和上傳進度的顯示。

 

除了上面提到的方法外,還可以使用第三方庫來實現大檔案上傳。常見的第三方庫有:

  • resumable.js
  • plupload
  • fine-uploader
  • tus-js-client

這些庫都提供了檔案分塊、斷點續傳、上傳進度等功能,可以讓你更快捷地實現大檔案上傳。

不過要注意的是,使用第三方庫可能會增加程式碼的複雜性和對第三方庫的依賴。在選擇使用第三方庫時需要權衡其優缺點,並確保它滿足你的需求。

 

關於檔案上傳需要了解的知識點:

  • HTML5 檔案上傳
  • 檔案上傳技術
  • 檔案上傳安全性
  • 分塊上傳
  • 斷點續傳
  • 雲端儲存