Die moderne Art
File Handling API verwenden
Deklarieren Sie zuerst das Attribut file_handlers
in Ihrem Web-App-Manifest. Für die File Handling API müssen Sie das Attribut action
(eine Verarbeitungs-URL) und das Attribut accept
angeben. Dabei handelt es sich um ein Objekt mit MIME-Typen als Schlüsseln und Arrays der jeweiligen Dateierweiterungen.
{
"file_handlers": [
{
"action": "./",
"accept": {
"image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
}
}
]
}
Als Nächstes müssen Sie die File Handling API verwenden, um geöffnete Dateien über die launchQueue
zu verarbeiten.
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
launchQueue.setConsumer((launchParams) => {
if (!launchParams.files.length) {
return;
}
for (const fileHandle of launchParams.files) {
// Handle the file.
}
});
}
Unterstützte Browser
- 102
- 102
- x
- x
Die klassische Art
Mit der klassischen DataTransferItem.getAsFile()
-Methode
Wenn die File Handling API nicht unterstützt wird, können Sie dennoch Dateien per Drag-and-drop aus dem Datei-Explorer in die App ziehen. Die Methode DataTransferItem.getAsFile()
gibt das File
-Objekt des Drag-Datenelements zurück.
Wenn das Element keine Datei ist, gibt diese Methode null
zurück. Sie können die Datei zwar lesen, aber nicht zurückschreiben. Diese Methode hat den Nachteil, dass sie keine Verzeichnisse unterstützt.
Progressive Enhancement
Das folgende Snippet verwendet die File Handling API, sofern verfügbar, und registriert zusätzlich Drag-and-drop-Handler, damit Dateien verarbeitet werden können.
Deklarieren Sie die Dateitypen, die im Manifest der Web-App verarbeitet werden können. Browser, die die File Handling API nicht unterstützen, ignorieren dies einfach.
{
"file_handlers": [
{
"action": "./",
"accept": {
"image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
}
}
]
}
// File Handling API
const handleLaunchFiles = () => {
window.launchQueue.setConsumer((launchParams) => {
if (!launchParams.files.length) {
return;
}
launchParams.files.forEach(async (handle) => {
const file = await handle.getFile();
console.log(`File: ${file.name}`);
// Do something with the file.
});
});
};
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
handleLaunchFiles();
}
// This is the drag and drop zone.
const elem = document.querySelector('main');
// Prevent navigation.
elem.addEventListener('dragover', (e) => {
e.preventDefault();
});
// Visually highlight the drop zone.
elem.addEventListener('dragenter', (e) => {
elem.style.outline = 'solid red 1px';
});
// Visually unhighlight the drop zone.
elem.addEventListener('dragleave', (e) => {
elem.style.outline = '';
});
// This is where the drop is handled.
elem.addEventListener('drop', async (e) => {
// Prevent navigation.
e.preventDefault();
// Unhighlight the drop zone.
elem.style.outline = '';
// Prepare an array of promises…
const fileHandlesPromises = [...e.dataTransfer.items]
// …by including only files (where file misleadingly means actual file _or_
// directory)…
.filter((item) => item.kind === 'file')
// …and, depending on previous feature detection…
.map((item) => item.getAsFile());
// Loop over the array of promises.
for await (const handle of fileHandlesPromises) {
// This is where we can actually exclusively act on the files.
if (handle.isFile) {
console.log(`File: ${handle.name}`);
// Do something with the file.
}
}
});
Weitere Informationen
- Installierte Webanwendungen als Datei-Handler verwenden
- File System Access API: Einfacher Zugriff auf lokale Dateien
Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="manifest" href="manifest.json" />
<title>How to handle files opened from the file explorer</title>
<link rel="stylesheet" href="style.css" />
<!-- TODO: Devsite - Removed inline handlers -->
<!-- <script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
const registration = await navigator.serviceWorker.register(
'sw.js',
);
console.log(
'Service worker registered for scope',
registration.scope,
);
});
}
</script>
<script src="script.js" type="module"></script> -->
</head>
<body>
<h1>How to handle files opened from the file explorer</h1>
<p>Install the app. After the installation, try opening an image file from the file explorer with the app.
</body>
</html>
html {
box-sizing: border-box;
font-family: system-ui, sans-serif;
color-scheme: dark light;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 1rem;
}
img {
height: auto;
max-width: 100%;
display: block;
}
if ('launchQueue' in window && 'files' in LaunchParams.prototype) {
launchQueue.setConsumer((launchParams) => {
if (!launchParams.files.length) {
return;
}
for (const fileHandle of launchParams.files) {
document.body.innerHTML += `${fileHandle.name}
`;
}
});
}