Signatur
Beschreibung
Mit webkitGetAsEntry() bekommt man zu einem DataTransferItem einen Eintrag der File and Directory Entries API. Anders als getAsFile(), das nur ein File-Objekt liefert, zeigt der zurückgegebene Eintrag, ob ein Verzeichnis oder eine Datei abgelegt wurde. Das ist der übliche Weg, um beim Ablegen per Drag & Drop ganze Ordner samt Unterordnern rekursiv einzulesen.
Das Ergebnis ist ein FileSystemEntry, genauer ein FileSystemFileEntry (isFile === true) oder ein FileSystemDirectoryEntry (isDirectory === true). Bei Dateien kommt man mit entry.file(callback) an das File-Objekt. Bei Verzeichnissen liest man den Inhalt über entry.createReader().readEntries(callback) aus.
Die Methode ist nur für Elemente mit kind === "file" sinnvoll. Bei Text- oder URL-Elementen (kind === "string") gibt sie null zurück. Trotz des webkit-Präfixes ist die Methode standardisiert und wird von allen modernen Browsern unter genau diesem Namen unterstützt. Eine Variante ohne Präfix gibt es nicht.
Rückgabewert
FileSystemEntry-Objekt für die abgelegte Datei bzw. das abgelegte Verzeichnis, oder null, wenn das Element keine Datei ist.Beispiele
Abgelegte Elemente als Datei oder Ordner erkennen
const dropZone = document.querySelector('#drop-zone');
dropZone.addEventListener('dragover', (event) => {
event.preventDefault(); // Ablegen erlauben
});
dropZone.addEventListener('drop', (event) => {
event.preventDefault();
for (const item of event.dataTransfer.items) {
const entry = item.webkitGetAsEntry();
if (!entry) continue; // kein Datei-Element
console.log(entry.isDirectory ? 'Ordner:' : 'Datei:', entry.fullPath);
}
});
Ordner rekursiv einlesen (mit Promises)
// Callback-APIs in Promises verpacken
const getFile = (fileEntry) =>
new Promise((resolve, reject) => fileEntry.file(resolve, reject));
// readEntries liefert Einträge in Blöcken – so lange aufrufen, bis ein leeres Array kommt
const readAllEntries = async (dirEntry) => {
const reader = dirEntry.createReader();
const all = [];
let batch;
do {
batch = await new Promise((resolve, reject) => reader.readEntries(resolve, reject));
all.push(...batch);
} while (batch.length > 0);
return all;
};
const collectFiles = async (entry) => {
if (entry.isFile) {
const file = await getFile(entry);
return [{ path: entry.fullPath, file }];
}
const children = await readAllEntries(entry);
const nested = await Promise.all(children.map(collectFiles));
return nested.flat();
};
document.body.addEventListener('dragover', (e) => e.preventDefault());
document.body.addEventListener('drop', async (event) => {
event.preventDefault();
// Einträge SOFORT (synchron) holen – nach dem ersten await ist die DataTransferItemList leer
const entries = [...event.dataTransfer.items]
.map((item) => item.webkitGetAsEntry())
.filter(Boolean);
const results = (await Promise.all(entries.map(collectFiles))).flat();
results.forEach(({ path, file }) => console.log(path, file.size, 'Bytes'));
});
Fallback auf getAsFile() ohne Ordner-Unterstützung
const handleItem = (item) => {
if (item.kind !== 'file') return null;
if (typeof item.webkitGetAsEntry === 'function') {
return item.webkitGetAsEntry();
}
// Ältere Umgebung: nur einzelne Dateien möglich
return item.getAsFile();
};
document.addEventListener('dragover', (e) => e.preventDefault());
document.addEventListener('drop', (event) => {
event.preventDefault();
const results = [...event.dataTransfer.items].map(handleItem);
console.log(results);
});
// Wichtig · Fallstricke
- Nur synchron im
drop-Handler aufrufen: Der Browser gibt dieDataTransferItemListnach dem Ereignis frei. Wer die Methode erst nach einemawaitoder in einemsetTimeoutaufruft, bekommt leere Listen odernull. Deshalb zuerst alle Einträge einsammeln und erst danach asynchron verarbeiten. readEntries()liefert Einträge in Blöcken: Chrome gibt höchstens 100 Einträge pro Aufruf zurück. Man mussreadEntries()daher so lange erneut aufrufen, bis ein leeres Array kommt, sonst fehlen bei großen Ordnern Dateien.- Die Methode funktioniert nur beim Ereignis
drop. Beidragover/dragentersind die Daten aus Datenschutzgründen geschützt (Protected Mode). - Bei Elementen mit
kind === "string"ist der Rückgabewertnull. Vor dem Zugriff also immer prüfen. - Die Einträge sind nur lesbar. Schreiben ist nicht möglich, und
fullPathist ein virtueller Pfad relativ zur Auswahl, kein echter Pfad im Dateisystem. - Trotz des Präfixes ist die Methode in Chrome, Edge, Firefox und Safari verfügbar. Für neuere Anwendungen in Chromium-Browsern gibt es alternativ
DataTransferItem.getAsFileSystemHandle()(File System Access API) mit Promise-basierter API und Schreibzugriff. Diese Methode wird aber noch nicht von allen Browsern unterstützt.