Dateien in JavaScript lesen

Die Auswahl und Interaktion mit Dateien auf dem lokalen Gerät des Nutzers ist eine der die am häufigsten verwendeten Funktionen des Webs. Nutzende können Dateien auswählen und Sie auf einen Server hochladen, z. B. wenn Sie Fotos teilen oder Steuerinformationen einreichen Dokumente. Außerdem können Websites sie lesen und bearbeiten, um die Daten über das Netzwerk zu übertragen. Auf dieser Seite erfahren Sie, wie Sie JavaScript für die Interaktion mit Dateien.

Die moderne Dateisystemzugriffs-API

Die File System Access API bietet die Möglichkeit, aus Dateien und auf dem lokalen System des Nutzers. Die Funktion ist in den meisten Chromium-basierten wie Chrome und Edge. Weitere Informationen finden Sie unter Die File System Access API.

Da die File System Access API nicht mit allen Browsern kompatibel ist, empfehlen die Verwendung von browser-fs-access, eine Hilfsbibliothek, die die neue API überall dort verwendet, wo sie verfügbar ist und wenn dies nicht der Fall ist.

Klassische Arbeit mit Dateien

In diesem Leitfaden erfahren Sie, wie Sie mithilfe alter JavaScript-Methoden mit Dateien interagieren.

Dateien auswählen

Es gibt zwei Möglichkeiten, Dateien auszuwählen: HTML-Eingabeelement und die Angabe eines Drag-and-drop-Bereich.

HTML-Eingabeelement

Nutzer können Dateien am einfachsten über die <input type="file"> -Element, das in allen gängigen Browsern unterstützt wird. Wenn ein Nutzer darauf klickt, eine oder mehrere Dateien auswählen, multiple über die integrierte Dateiauswahl ihres Betriebssystems UI. Wenn der Nutzer eine oder mehrere Dateien ausgewählt hat, wird der Wert change des Elements ausgelöst wird. Sie können über event.target.files auf die Liste der Dateien zugreifen, die ist ein FileList-Objekt. Jedes Element im FileList ist ein File-Objekt.

<!-- 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>

Im folgenden Beispiel können Nutzer mehrere Dateien über ihre integrierte Benutzeroberfläche zur Dateiauswahl des Systems und protokolliert jede ausgewählte Datei im .

Beschränken, welche Dateitypen Nutzer auswählen können

In einigen Fällen möchten Sie vielleicht die Dateitypen einschränken, die Nutzer auswählen können. Für Beispiel: Eine Bildbearbeitungs-App sollte nur Bilder und keine Textdateien akzeptieren. Zum Einstellen Dateityp-Einschränkungen, fügen Sie eine accept -Attribut zum Eingabeelement hinzu, um anzugeben, welche Dateitypen akzeptiert werden:

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

Benutzerdefiniertes Drag-and-drop

In einigen Browsern ist das <input type="file">-Element auch ein Drop-Ziel. sodass Nutzende Dateien per Drag-and-drop in Ihre App ziehen können. Dieses Drop-Ziel klein und schwer zu bedienen ist. Nachdem Sie die Hauptfunktionen ein <input type="file">-Element haben, können Sie ein großes, benutzerdefiniertes Drag-and-drop Oberfläche.

Drop-Zone auswählen

Die Verkaufsfläche hängt vom Design der App ab. Vielleicht möchten Sie nur als Fallfläche, Sie können aber das gesamte Fenster nutzen.

<ph type="x-smartling-placeholder">
</ph> Screenshot von Squoosh, einer Webanwendung zur Bildkomprimierung. <ph type="x-smartling-placeholder">
</ph> Squoosh macht das gesamte Fenster zu einer Drop-Zone.

Mit der Bildkomprimierungs-App Squoosh können Nutzer ein Bild an eine beliebige Stelle in die und klicken Sie auf Image auswählen, um den <input type="file"> aufzurufen. -Elements. Was auch immer du als Drop-Zone wählst, achte darauf, dass es für den Nutzer klar erkennbar ist. dass sie Dateien auf diese Oberfläche ziehen können.

Legendenbereich definieren

Um ein Element als Drag-and-drop-Bereich zu aktivieren, erstellen Sie Listener für zwei Ereignisse: dragover und drop. Das dragover-Ereignis aktualisiert die Browser-Benutzeroberfläche, um visuell anzuzeigen, dass der die Drag-and-drop-Aktion ist das Erstellen einer Kopie der Datei. Das drop-Ereignis wird ausgelöst nachdem Nutzende die Dateien auf der Oberfläche abgelegt haben. Wie beim Eingabeelement geben Sie kann auf die Liste der Dateien von event.dataTransfer.files zugreifen, wobei es sich um eine Objekt FileList. Jedes Element im FileList ist ein File-Objekt.

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() und event.preventDefault() das Standardverhalten des Browsers beenden und stattdessen den Code ausführen. Ohne sie sonst würde der Browser die Seite verlassen und die Dateien öffnen die der Nutzer in das Browserfenster gezogen hat.

Eine Live-Demo finden Sie unter Benutzerdefiniertes Drag-and-drop.

Wie sieht es mit Verzeichnissen aus?

Leider gibt es keine gute Möglichkeit, mit JavaScript auf ein Verzeichnis zuzugreifen.

Die webkitdirectory Attribut für das Element <input type="file"> kann der Nutzer ein Verzeichnis auswählen oder Verzeichnisse entfernen. Diese Funktion wird in den meisten gängigen Browsern unterstützt. außer Firefox für Android und Safari unter iOS.

Wenn Drag-and-drop aktiviert ist, könnte ein Nutzer versuchen, ein Verzeichnis per Drag-and-drop Drop-Zone. Wenn das Drop-Ereignis ausgelöst wird, enthält es ein File-Objekt für das Ereignis Verzeichnis, bietet aber keinen Zugriff auf die Dateien im Verzeichnis.

Dateimetadaten lesen

Das Objekt File enthält Metadaten zur Datei. Die meisten Browser geben den Dateinamen, die Größe der Datei und den MIME-Typ an. Je nachdem, auf der Plattform nutzen, können verschiedene Browser unterschiedliche oder zusätzliche Informationen.

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

In der input-type-file können Sie dies in Aktion sehen. .

Inhalt einer Datei lesen

Verwenden Sie FileReader für Folgendes: Inhalt eines File-Objekts in den Speicher lesen. Du kannst FileReader anweisen, eine Datei als Array-Zwischenspeicher lesen, eine Daten-URL, oder Text:

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

In diesem Beispiel wird eine vom Nutzer bereitgestellte File gelesen und dann in Daten umgewandelt URL und verwendet diese Daten-URL, um das Bild in einem img-Element anzuzeigen. Informationen dazu, wie Sie überprüfen können, ob der Nutzer eine Bilddatei ausgewählt hat, finden Sie in der read-image-file-Demo.

Fortschritt eines Dateilesevorgangs überwachen

Beim Lesen großer Dateien kann es hilfreich sein, den Nutzenden wie weit der Lesefortschritt fortgeschritten ist. Verwenden Sie dazu die Methode progress Ereignis bereitgestellt von FileReader. Das progress-Ereignis hat zwei Eigenschaften: loaded (der gelesene Betrag) und total (der gelesene Betrag).

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

Hero-Image von Vincent Botta von Unsplash