Odczytuj pliki w języku JavaScript

Wybieranie plików na urządzeniu lokalnym użytkownika i wchodzenie z nimi w interakcję to jedna z z najczęściej używanych funkcji internetu. Umożliwia użytkownikom wybieranie plików przesyłać je na serwer, np. przy udostępnianiu zdjęć lub przesyłaniu podatku; dokumenty. Umożliwia też witrynom ich odczytywanie i manipulowanie bez konieczności aby przenieść dane w sieci. Z tego artykułu dowiesz się, jak korzystać JavaScriptu do interakcji z plikami.

Nowoczesny interfejs File System Access API

Interfejs File System Access API umożliwia odczyt i zapis w plikach oraz katalogi w lokalnym systemie użytkownika. Jest dostępny w większości przeglądarek opartych na Chromium takich jak Chrome i Edge. Więcej informacji: Interfejs File System Access API.

Interfejs File System Access API nie jest zgodny ze wszystkimi przeglądarkami, zalecamy użycie polecenia browser-fs-access, biblioteka pomocnicza, która używa nowego interfejsu API wszędzie tam, gdzie jest dostępny w przypadku starszych rozwiązań.

Klasyczna praca z plikami

Z tego przewodnika dowiesz się, jak korzystać z plików za pomocą starszych metod JavaScript.

Wybierz pliki

Istnieją 2 główne sposoby wybierania plików: za pomocą elementu wejściowego HTML oraz tagu strefie przeciągania i upuszczania.

Element do wprowadzania danych HTML

Najłatwiejszym sposobem wybierania plików przez użytkowników jest korzystanie z <input type="file"> który jest obsługiwany w każdej popularnej przeglądarce. Po kliknięciu użytkownik może wybierz plik lub wiele plików, jeśli multiple przy użyciu wbudowanego narzędzia wyboru plików w systemie operacyjnym Interfejs. Gdy użytkownik wybierze jeden lub więcej plików, właściwość change elementu pożary zdarzeń. Możesz uzyskać dostęp do listy plików z usługi event.target.files, która jest obiektem FileList. Każdy element w tabeli FileList jest obiektem 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>

Ten przykład pozwala użytkownikowi wybrać wiele plików za pomocą systemu operacyjnego wbudowanego interfejsu użytkownika systemu do wyboru plików, a następnie loguje każdy wybrany plik w konsoli.

Ogranicz typy plików, które użytkownicy mogą wybierać

W niektórych przypadkach możesz chcieć ograniczyć typy plików, które mogą wybierać użytkownicy. Dla: np. aplikacja do edycji obrazów powinna akceptować tylko obrazy, a nie pliki tekstowe. Aby ustawić ograniczeń typów plików, dodaj accept do elementu wejściowego, aby określić akceptowane typy plików:

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

Niestandardowe przeciąganie i upuszczanie

W niektórych przeglądarkach element <input type="file"> jest też elementem docelowym, co pozwala użytkownikom przeciągać i upuszczać pliki do aplikacji. Jednak ta wartość docelowa jest mały i może być trudny w obsłudze. Zamiast tego po udostępnieniu podstawowych funkcji za pomocą elementu <input type="file">, możesz przeciągnąć i upuścić elementy niestandardowe na różnych powierzchniach.

Wybierz swoją strefę

Miejsce upuszczania zależy od projektu aplikacji. Być może warto wybrać tylko możesz użyć całego okna, ale możesz użyć całego okna.

Zrzut ekranu przedstawiający Squoosh, aplikację internetową do kompresji obrazów.
Funkcja Squoosh sprawia, że całe okno zmienia się w strefę upuszczania.

Aplikacja do kompresji obrazów Squoosh pozwala użytkownikowi przeciągnąć obraz w dowolne miejsce i kliknij Wybierz obraz, aby wywołać <input type="file"> . Cokolwiek wybierzesz jako strefę upuszczania, musisz wyraźnie wskazać użytkownikowi że użytkownicy mogą przeciągać pliki na tę platformę.

Definiowanie strefy upuszczania

Aby włączyć możliwość używania elementu jako strefy przeciągania i upuszczania, utwórz detektory dla dwa wydarzenia: dragover i drop. Zdarzenie dragover aktualizuje interfejs przeglądarki, wizualnie wskazując, przeciąganie i upuszczanie oznacza utworzenie kopii pliku. Zdarzenie drop jest uruchamiane gdy użytkownik upuszcza pliki na powierzchnię. Podobnie jak w przypadku elementu wejściowego, ma dostęp do listy plików z usługi event.dataTransfer.files, która jest FileList. Każdy element w tabeli FileList jest obiektem 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() i event.preventDefault() zatrzymaj domyślne działanie przeglądarki i pozwól na uruchomienie kodu. Bez nich przeglądarka w przeciwnym razie opuści stronę i otworzy pliki użytkownik upuścił się do okna przeglądarki.

Instrukcje na żywo znajdziesz w artykule Niestandardowe przeciąganie i upuszczanie.

A co z katalogami?

Niestety nie ma dobrego sposobu na uzyskanie dostępu do katalogu za pomocą JavaScriptu.

webkitdirectory w elemencie <input type="file"> pozwala użytkownikowi wybrać katalog lub katalogów. Jest obsługiwana przez większość najpopularniejszych przeglądarek. oprócz Firefoksa na Androida i Safari na iOS.

Jeśli włączone jest przeciąganie i upuszczanie, użytkownik może próbować przeciągnąć katalog do w strefie wytłaczania. Po uruchomieniu zdarzenia drop zawiera obiekt File dla katalogu, ale nie zapewnia dostępu do żadnych plików w katalogu.

Odczytywanie metadanych pliku

Obiekt File zawiera metadane dotyczące pliku. Większość przeglądarek i podać nazwę pliku, jego rozmiar i typ MIME, na platformie, różne przeglądarki mogą wyświetlać różne lub dodatkowe i informacjami o nich.

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});
  }
}

Aby zobaczyć, jak to działa, zobacz input-type-file wersji demonstracyjnej.

Odczytywanie zawartości pliku

Użyj aplikacji FileReader, aby: odczytuje zawartość obiektu File w pamięci. Możesz powiedzieć FileReader, aby odczytuje plik jako bufor tablicy, adres URL danych, lub tekst:

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);
}

W tym przykładzie odczytuje on pole File dostarczone przez użytkownika, a potem konwertuje go na dane i wykorzystuje ten adres URL danych do wyświetlenia obrazu w elemencie img. Aby dowiedzieć się, jak sprawdzić, czy użytkownik wybrał plik obrazu, zapoznaj się z read-image-file – wersja demonstracyjna.

Monitorowanie postępu odczytu pliku

Przy odczytywaniu dużych plików pomocne może być udostępnienie użytkownikowi informacji na temat UX, jak daleko zaszedł odczyt. Do tego celu użyj funkcji progress wydarzenie dostarczone przez: FileReader. Zdarzenie progress ma 2 właściwości: loaded (kwota odczytana) i total (kwotę do przeczytania).

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);
}

Baner powitalny: Vincent Botta z Unsplash