以 JavaScript 讀取檔案

在使用者本機裝置上選取檔案並進行互動 網路上最常用的功能。使用者可以選取檔案 再將這些內容上傳到伺服器,例如在共享相片或提交稅金時 文件。還能讓網站 在整個網路中轉移資料本頁將逐步說明如何使用 可與檔案互動的 JavaScript。

現代化的 File System Access API

File System Access API 提供讀取和寫入檔案和 使用者本機系統的目錄適用於大多數以 Chromium 為基礎的方式 例如 Chrome 和 Edge詳情請參閱 File System Access API

File System Access API 與某些瀏覽器不相容,因此 建議您使用 browser-fs-access、 每當有新的 API 可用時,這個輔助程式庫就會使用 某些舊版方法可能就不適用。

以傳統方式處理檔案

本指南將說明如何使用舊版 JavaScript 方法與檔案互動。

選取檔案

選取檔案的主要方式有兩種: HTML 輸入元素,然後使用 拖曳可用區

HTML 輸入元素

讓使用者輕鬆選取檔案 <input type="file">敬上 元素,但每個主要瀏覽器都支援這個元素。使用者點選這個元件後 選取一或多個檔案 multiple敬上 透過作業系統內建的檔案選項,包含在內 第一種是使用無代碼解決方案 AutoML 透過使用者介面建立機器學習模型使用者選取一或多個檔案後,元素的 change 事件。你可以從「event.target.files」存取檔案清單, 是 FileList 物件。 FileList 中的每個項目都是 File 物件。

<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
  const fileSelector = document.getElementById('file-selector');
  fileSelector.addEventListener('change', (event) => {
    const fileList = event.target.files;
    console.log(fileList);
  });
</script>

以下範例可讓使用者在作業環境中以作業方式選取多個檔案 系統內建的檔案選取 UI 然後將各個選取檔案記錄為 控制台。

限制使用者可選取的檔案類型

在某些情況下,您可能會想限制使用者可選取的檔案類型。適用對象 例如,圖片編輯應用程式應該只接受圖片,不能接受文字檔。如何設定 檔案類型限制,請新增 accept敬上 屬性新增至輸入元素,以指定系統接受的檔案類型:

<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">

自訂拖曳

在某些瀏覽器中,<input type="file"> 元素也是放置目標 讓使用者可以將檔案拖曳到應用程式中。不過,這種下滑目標 極小且難以使用而在您使用 <input type="file"> 元素時,您可以提供大型的自訂拖曳項目 途徑。

選擇放置區

放置途徑取決於應用程式設計。您可能只想 部分成為放置途徑,但您可以使用整個視窗。

Squoosh 的螢幕截圖,這是圖片壓縮網頁應用程式。
Squoosh 將整個視窗變成捨棄區域。

圖片壓縮應用程式 Squoosh 的使用者將圖片拖曳到 並按一下「Select an image」,叫用 <input type="file"> 元素。無論選擇哪種放置區域,都得清楚告知使用者這項資訊 將檔案拖曳到這個介面上

定義捨棄可用區

如要啟用元素做為拖曳區域,請為 兩項事件:dragoverdropdragover 事件會更新瀏覽器 UI,以視覺化的方式指出 拖曳動作會建立檔案副本。drop 事件會觸發 。與輸入元素一樣 可存取「event.dataTransfer.files」的檔案清單, FileList 物件。每項 FileList 中的項目是 File 物件。

const dropArea = document.getElementById('drop-area');

dropArea.addEventListener('dragover', (event) => {
  event.stopPropagation();
  event.preventDefault();
  // Style the drag-and-drop as a "copy file" operation.
  event.dataTransfer.dropEffect = 'copy';
});

dropArea.addEventListener('drop', (event) => {
  event.stopPropagation();
  event.preventDefault();
  const fileList = event.dataTransfer.files;
  console.log(fileList);
});

event.stopPropagation()敬上 和 event.preventDefault() 停止瀏覽器的預設行為並讓系統執行程式碼。沒有的話 瀏覽器就會離開網頁並開啟檔案 使用者放進瀏覽器視窗。

如需現場示範,請參閱「自訂拖曳」一文。

那目錄呢?

但很抱歉,使用 JavaScript 存取目錄是不錯的方法。

webkitdirectory <input type="file"> 元素上的屬性可讓使用者選擇目錄 檔案或目錄多數主要瀏覽器都支援這項做法 但 iOS 版的 Firefox 和 iOS 版 Safari

如果啟用了拖曳功能,使用者可能會嘗試將目錄拖曳到 放置區域Drop 事件觸發時,會包含 File 物件 ,但不提供該目錄內任何檔案的存取權。

讀取檔案中繼資料

File 物件包含檔案的中繼資料,多數瀏覽器 請提供檔案名稱、檔案大小以及 MIME 類型。 不同瀏覽器採用的 可能不準確或不適當

function getMetadataForFileList(fileList) {
  for (const file of fileList) {
    // Not supported in Safari for iOS.
    const name = file.name ? file.name : 'NOT SUPPORTED';
    // Not supported in Firefox for Android or Opera for Android.
    const type = file.type ? file.type : 'NOT SUPPORTED';
    // Unknown cross-browser support.
    const size = file.size ? file.size : 'NOT SUPPORTED';
    console.log({file, name, type, size});
  }
}

您可以在 input-type-file 中查看實際運作情形 示範。

讀取檔案內容

使用 FileReader: 將 File 物件的內容讀取到記憶體。您可以指示「FileReader」執行下列操作: 將檔案讀取為陣列緩衝區 資料網址, 或文字

function readImage(file) {
  // Check if the file is an image.
  if (file.type && !file.type.startsWith('image/')) {
    console.log('File is not an image.', file.type, file);
    return;
  }

  const reader = new FileReader();
  reader.addEventListener('load', (event) => {
    img.src = event.target.result;
  });
  reader.readAsDataURL(file);
}

這個範例會讀取使用者提供的 File,然後將其轉換為資料 網址,並使用該資料網址在 img 元素中顯示圖片。 如要瞭解如何確認使用者已選取圖片檔,請參閱 read-image-file 示範。

監控檔案讀取進度

閱讀大型檔案時,提供一些 UX 協助使用者瞭解 讀取進度為此,請使用 progress敬上 事件 (由「FileReader」提供)。progress 事件有兩個屬性: loaded (讀取量) 和 total (要閱讀的量)。

function readFile(file) {
  const reader = new FileReader();
  reader.addEventListener('load', (event) => {
    const result = event.target.result;
    // Do something with result
  });

  reader.addEventListener('progress', (event) => {
    if (event.loaded && event.total) {
      const percent = (event.loaded / event.total) * 100;
      console.log(`Progress: ${Math.round(percent)}`);
    }
  });
  reader.readAsDataURL(file);
}

主頁橫幅 (由 Unsplash 提供)