Start · Sprachen · JavaScript · Referenz · Window.showOpenFilePicker()

Window.showOpenFilePicker()

Methode

Öffnet einen nativen Dateiauswahldialog und liefert ein Promise mit einem Array von <code>FileSystemFileHandle</code>-Objekten für die ausgewählten Dateien.

seit JavaScript File System Access API – Chromium 86+ (Chrome, Edg Kategorie: webapi

Signatur

Window.showOpenFilePicker(options)

Beschreibung

Die Methode showOpenFilePicker() gehört zur File System Access API. Sie zeigt den Dateiauswahldialog des Betriebssystems an und gibt statt reiner File-Objekte (wie bei <input type="file">) Handles vom Typ FileSystemFileHandle zurück. Über ein solches Handle liest man die Datei mit getFile() und kann sie nach Erteilung der Berechtigung mit createWritable() auch direkt überschreiben.

Gedacht ist die Methode für Web-Anwendungen, die sich wie Desktop-Programme verhalten sollen: Editoren, Bild- und Grafikwerkzeuge oder IDEs, die eine Datei öffnen, bearbeiten und an derselben Stelle wieder speichern. Handles lassen sich zudem in IndexedDB ablegen, damit man zuletzt geöffnete Dateien später erneut öffnen kann (die Berechtigung muss dann meist erneut bestätigt werden).

Wichtig: Der Aufruf braucht eine vorübergehende Benutzeraktivierung (z. B. einen Klick), funktioniert nur in einem sicheren Kontext (HTTPS oder localhost) und nicht in plattformübergreifenden (cross-origin) iframes. Bricht der Nutzer den Dialog ab, wird das Promise mit einer AbortError-DOMException zurückgewiesen. Das sollte man immer abfangen.

Rückgabewert

Typ
Promise<FileSystemFileHandle[]>
Beschreibung
Ein Promise, das mit einem Array von FileSystemFileHandle-Objekten erfüllt wird. Das Array ist auch ohne multiple immer ein Array (dann mit genau einem Eintrag). Es wird mit AbortError (Abbruch), SecurityError (unsicherer Kontext, cross-origin iframe, keine Benutzeraktivierung) oder TypeError (ungültige types) zurückgewiesen.

Beispiele

Textdatei öffnen und Inhalt anzeigen

const button = document.querySelector('#open');
const editor = document.querySelector('#editor');

button.addEventListener('click', async () => {
  try {
    const [handle] = await window.showOpenFilePicker({
      types: [{
        description: 'Textdateien',
        accept: { 'text/plain': ['.txt', '.md'] }
      }],
      excludeAcceptAllOption: true
    });
    const file = await handle.getFile();
    editor.value = await file.text();
    console.log(`Geöffnet: ${file.name} (${file.size} Bytes)`);
  } catch (err) {
    if (err.name === 'AbortError') return; // Nutzer hat abgebrochen
    console.error('Fehler beim Öffnen:', err);
  }
});
Geöffnet: notizen.txt (1342 Bytes)

Mehrere Bilder auswählen, mit Fallback auf <input type="file">

const pickImages = async () => {
  if (!('showOpenFilePicker' in window)) {
    // Fallback für Firefox/Safari
    return new Promise((resolve) => {
      const input = Object.assign(document.createElement('input'), {
        type: 'file', accept: 'image/*', multiple: true
      });
      input.addEventListener('change', () => resolve([...input.files]));
      input.click();
    });
  }
  const handles = await window.showOpenFilePicker({
    multiple: true,
    id: 'bilder',
    startIn: 'pictures',
    types: [{ description: 'Bilder', accept: { 'image/*': ['.png', '.jpg', '.jpeg', '.webp'] } }]
  });
  return Promise.all(handles.map((h) => h.getFile()));
};

document.querySelector('#pick').addEventListener('click', async () => {
  const files = await pickImages();
  console.log(files.map((f) => f.name));
});
["urlaub.jpg", "logo.png"]

Geöffnete Datei direkt überschreiben

let fileHandle;

document.querySelector('#open').addEventListener('click', async () => {
  [fileHandle] = await window.showOpenFilePicker();
  const file = await fileHandle.getFile();
  document.querySelector('#editor').value = await file.text();
});

document.querySelector('#save').addEventListener('click', async () => {
  const opts = { mode: 'readwrite' };
  if ((await fileHandle.queryPermission(opts)) !== 'granted' &&
      (await fileHandle.requestPermission(opts)) !== 'granted') {
    console.warn('Keine Schreibberechtigung');
    return;
  }
  const writable = await fileHandle.createWritable();
  await writable.write(document.querySelector('#editor').value);
  await writable.close(); // erst hier wird auf die Platte geschrieben
  console.log('Gespeichert');
});
Gespeichert

// Wichtig · Fallstricke

  • Browser-Unterstützung: Nur in Chromium-Browsern auf dem Desktop (Chrome/Edge 86+, Opera). Firefox und Safari unterstützen die Methode nicht, auf Android fehlt sie ebenfalls. Vorher immer mit 'showOpenFilePicker' in window prüfen und auf <input type="file"> ausweichen.
  • Benutzeraktivierung nötig: Ein Aufruf ohne vorherige Nutzerinteraktion, etwa beim Laden der Seite oder nach langen await-Ketten, scheitert mit SecurityError.
  • Abbruch ist kein Fehler: Schließt der Nutzer den Dialog, wird das Promise mit AbortError zurückgewiesen. Diesen Fall gesondert behandeln und keine Fehlermeldung zeigen.
  • Nur Lesezugriff zu Beginn: Das Handle hat zunächst nur Leserechte. Zum Schreiben ist requestPermission({ mode: 'readwrite' }) nötig, was eine weitere Rückfrage auslösen kann.
  • Sicherheit: Nur in sicheren Kontexten (HTTPS) und nicht in cross-origin iframes verfügbar. Systemordner und sensible Dateien kann der Browser sperren. Inhalte aus gewählten Dateien nie ungeprüft per innerHTML einfügen, sonst droht XSS.
  • Die Methode liefert immer ein Array. Die Destrukturierung const [handle] = … ist deshalb die übliche Schreibweise.