Met de File System Access API kunnen webapps rechtstreeks wijzigingen in bestanden en mappen op het apparaat van de gebruiker lezen en opslaan.
Wat is de File System Access API?
Met de File System Access API kunnen ontwikkelaars krachtige webapps bouwen die communiceren met bestanden op het lokale apparaat van de gebruiker, zoals IDE's, foto- en video-editors, teksteditors en meer. Nadat een gebruiker een webapp toegang heeft verleend, kan deze API bestanden en mappen op het apparaat van de gebruiker rechtstreeks lezen en er wijzigingen in opslaan. Naast het lezen en schrijven van bestanden biedt de File System Access API de mogelijkheid om een directory te openen en de inhoud ervan te inventariseren.
Als je al eerder met het lezen en schrijven van bestanden hebt gewerkt, zal veel van wat ik ga delen je bekend voorkomen. Ik raad je aan om het toch te lezen, want niet alle systemen zijn hetzelfde.
De File System Access API wordt ondersteund door de meeste Chromium-browsers op Windows, macOS, ChromeOS, Linux en Android. Een opvallende uitzondering is Brave, waar deze momenteel alleen beschikbaar is achter een vlag .
De API voor bestandssysteemtoegang gebruiken
Om de kracht en bruikbaarheid van de File System Access API te demonstreren, heb ik een teksteditor voor één bestand geschreven. Hiermee kun je een tekstbestand openen, bewerken, de wijzigingen opslaan op schijf, of een nieuw bestand starten en de wijzigingen opslaan op schijf. Het is niets bijzonders, maar biedt voldoende om je de concepten te helpen begrijpen.
Browserondersteuning
Functiedetectie
Om erachter te komen of de File System Access API wordt ondersteund, controleert u of de pickermethode waarin u geïnteresseerd bent, bestaat.
if ('showOpenFilePicker' in self) {
// The `showOpenFilePicker()` method of the File System Access API is supported.
}
Probeer het eens
Bekijk de File System Access API in actie in de demo van de teksteditor .
Een bestand lezen van het lokale bestandssysteem
Het eerste gebruiksvoorbeeld dat ik wil aanpakken, is de gebruiker vragen om een bestand te selecteren, dat bestand vervolgens te openen en vanaf de schijf te lezen.
Vraag de gebruiker om een bestand te kiezen om te lezen
Het toegangspunt tot de File System Access API is window.showOpenFilePicker()
. Wanneer deze wordt aangeroepen, wordt een dialoogvenster voor het selecteren van bestanden geopend en wordt de gebruiker gevraagd een bestand te selecteren. Nadat een bestand is geselecteerd, retourneert de API een reeks bestandshandles. Met een optionele parameter options
' kunt u het gedrag van de bestandskiezer beïnvloeden, bijvoorbeeld door de gebruiker toe te staan meerdere bestanden, mappen of verschillende bestandstypen te selecteren. Zonder opgegeven opties kan de bestandskiezer één bestand selecteren. Dit is perfect voor een teksteditor.
Net als bij veel andere krachtige API's moet het aanroepen van showOpenFilePicker()
in een beveiligde context gebeuren en moet dit vanuit een gebruikersgebaar gebeuren.
let fileHandle;
butOpenFile.addEventListener('click', async () => {
// Destructure the one-element array.
[fileHandle] = await window.showOpenFilePicker();
// Do something with the file handle.
});
Zodra de gebruiker een bestand selecteert, retourneert showOpenFilePicker()
een array met handles. In dit geval een array met één element en één FileSystemFileHandle
die de eigenschappen en methoden bevat die nodig zijn om met het bestand te communiceren.
Het is handig om een verwijzing naar de bestandsnaam te bewaren, zodat deze later gebruikt kan worden. Deze is nodig om wijzigingen in het bestand op te slaan of andere bestandsbewerkingen uit te voeren.
Een bestand lezen van het bestandssysteem
Nu je een handle naar een bestand hebt, kun je de eigenschappen van het bestand ophalen of het bestand zelf benaderen. Voor nu lees ik de inhoud ervan. Het aanroepen van handle.getFile()
retourneert een File
object, dat een blob bevat. Om de gegevens uit de blob op te halen, roep je een van de methoden aan ( slice()
, stream()
, text()
arrayBuffer()
).
const file = await fileHandle.getFile();
const contents = await file.text();
Het File
object dat door FileSystemFileHandle.getFile()
wordt geretourneerd, is alleen leesbaar zolang het onderliggende bestand op schijf niet is gewijzigd. Als het bestand op schijf wordt gewijzigd, wordt het File
object onleesbaar en moet u getFile()
opnieuw aanroepen om een nieuw File
object te verkrijgen dat de gewijzigde gegevens kan lezen.
Alles bij elkaar optellen
Wanneer gebruikers op de knop Openen klikken, toont de browser een bestandskiezer. Zodra ze een bestand hebben geselecteerd, leest de app de inhoud en plaatst deze in een <textarea>
.
let fileHandle;
butOpenFile.addEventListener('click', async () => {
[fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const contents = await file.text();
textArea.value = contents;
});
Schrijf het bestand naar het lokale bestandssysteem
In de teksteditor zijn er twee manieren om een bestand op te slaan: Opslaan en Opslaan als . Opslaan schrijft de wijzigingen terug naar het oorspronkelijke bestand met behulp van de eerder opgehaalde bestandshandle. Opslaan als maakt echter een nieuw bestand aan en vereist dus een nieuwe bestandshandle.
Een nieuw bestand maken
Om een bestand op te slaan, roept u showSaveFilePicker()
aan. De bestandskiezer wordt dan in de "opslaan"-modus weergegeven, zodat de gebruiker een nieuw bestand kan kiezen om op te slaan. Voor de teksteditor wilde ik ook automatisch een .txt
extensie toevoegen, dus gaf ik een aantal extra parameters op.
async function getNewFileHandle() {
const options = {
types: [
{
description: 'Text Files',
accept: {
'text/plain': ['.txt'],
},
},
],
};
const handle = await window.showSaveFilePicker(options);
return handle;
}
Wijzigingen opslaan op schijf
Je vindt alle code voor het opslaan van wijzigingen in een bestand in mijn demo van de teksteditor op GitHub . De belangrijkste interacties met het bestandssysteem staan in fs-helpers.js
. In zijn eenvoudigste vorm ziet het proces eruit als de volgende code. Ik zal elke stap doorlopen en uitleggen.
// fileHandle is an instance of FileSystemFileHandle..
async function writeFile(fileHandle, contents) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();
}
Het schrijven van gegevens naar schijf maakt gebruik van een FileSystemWritableFileStream
-object, een subklasse van WritableStream
. Creëer de stream door createWritable()
aan te roepen op het bestandshandle-object. Wanneer createWritable()
wordt aangeroepen, controleert de browser eerst of de gebruiker schrijfrechten voor het bestand heeft. Als deze rechten niet zijn verleend, vraagt de browser de gebruiker om toestemming. Als deze rechten niet zijn verleend, genereert createWritable()
een DOMException
en kan de app niet naar het bestand schrijven. In de teksteditor worden de DOMException
objecten verwerkt in de saveFile()
-methode.
De write()
-methode accepteert een string, wat nodig is voor een teksteditor. Maar hij kan ook een BufferSource of een Blob accepteren. Je kunt er bijvoorbeeld een stream rechtstreeks naartoe leiden:
async function writeURLToFile(fileHandle, url) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Make an HTTP request for the contents.
const response = await fetch(url);
// Stream the response into the file.
await response.body.pipeTo(writable);
// pipeTo() closes the destination pipe by default, no need to close it.
}
U kunt ook seek()
of truncate()
binnen de stream uitvoeren om het bestand op een specifieke positie bij te werken of de bestandsgrootte te wijzigen.
Een voorgestelde bestandsnaam en startmap opgeven
In veel gevallen wilt u dat uw app een standaardbestandsnaam of -locatie voorstelt. Een teksteditor kan bijvoorbeeld de standaardbestandsnaam Untitled Text.txt
voorstellen in plaats van Untitled
. U kunt dit bereiken door de eigenschap suggestedName
door te geven als onderdeel van de showSaveFilePicker
-opties.
const fileHandle = await self.showSaveFilePicker({
suggestedName: 'Untitled Text.txt',
types: [{
description: 'Text documents',
accept: {
'text/plain': ['.txt'],
},
}],
});
Hetzelfde geldt voor de standaard startmap. Als u een teksteditor bouwt, kunt u het dialoogvenster 'Bestand opslaan' of 'Bestand openen' het beste starten in de documents
, terwijl u voor een afbeeldingseditor de pictures
kunt gebruiken. U kunt een standaard startmap voorstellen door een eigenschap startIn
door te geven aan de methoden showSaveFilePicker
, showDirectoryPicker()
of showOpenFilePicker
, zoals hier.
const fileHandle = await self.showOpenFilePicker({
startIn: 'pictures'
});
De lijst met bekende systeemmappen is:
-
desktop
: De bureaubladmap van de gebruiker, indien deze bestaat. -
documents
: Map waarin doorgaans door de gebruiker gemaakte documenten worden opgeslagen. -
downloads
: map waarin gedownloade bestanden doorgaans worden opgeslagen. -
music
: Map waar doorgaans audiobestanden worden opgeslagen. -
pictures
: Map waar doorgaans foto's en andere stilstaande beelden worden opgeslagen. -
videos
: map waarin doorgaans video's of films worden opgeslagen.
Naast bekende systeemmappen kunt u ook een bestaande bestands- of map-handle als waarde voor startIn
opgeven. Het dialoogvenster wordt dan in dezelfde map geopend.
// Assume `directoryHandle` is a handle to a previously opened directory.
const fileHandle = await self.showOpenFilePicker({
startIn: directoryHandle
});
Het doel van verschillende bestandskiezers specificeren
Soms hebben applicaties verschillende kiezers voor verschillende doeleinden. Een RTF-editor kan de gebruiker bijvoorbeeld toestaan om tekstbestanden te openen, maar ook om afbeeldingen te importeren. Standaard wordt elke bestandskiezer geopend op de laatst onthouden locatie. U kunt dit omzeilen door id
waarden voor elk type kiezer op te slaan. Als een id
is opgegeven, onthoudt de implementatie van de bestandskiezer een aparte laatst gebruikte directory voor die id
.
const fileHandle1 = await self.showSaveFilePicker({
id: 'openText',
});
const fileHandle2 = await self.showSaveFilePicker({
id: 'importImage',
});
Bestands- of directory-handles opslaan in IndexedDB
Bestands- en directory-handles zijn serialiseerbaar, wat betekent dat u een bestands- of directory-handle kunt opslaan in IndexedDB, of postMessage()
kunt aanroepen om ze tussen dezelfde hoofdbron te verzenden.
Het opslaan van bestands- of directory-handles in IndexedDB betekent dat je de status kunt opslaan of kunt onthouden aan welke bestanden of directory's een gebruiker werkte. Dit maakt het mogelijk om een lijst bij te houden van recent geopende of bewerkte bestanden, aan te bieden om het laatste bestand opnieuw te openen wanneer de app wordt geopend, de vorige werkdirectory te herstellen, en meer. In de teksteditor sla ik een lijst op van de vijf meest recente bestanden die de gebruiker heeft geopend, zodat deze bestanden opnieuw toegankelijk zijn.
Het volgende codevoorbeeld toont het opslaan en ophalen van een bestands- en directory-handle. Je kunt dit in actie zien op Glitch. (Ik gebruik de idb-keyval- bibliotheek voor de beknoptheid.)
import { get, set } from 'https://unpkg.com/[email protected]/dist/esm/index.js';
const pre1 = document.querySelector('pre.file');
const pre2 = document.querySelector('pre.directory');
const button1 = document.querySelector('button.file');
const button2 = document.querySelector('button.directory');
// File handle
button1.addEventListener('click', async () => {
try {
const fileHandleOrUndefined = await get('file');
if (fileHandleOrUndefined) {
pre1.textContent = `Retrieved file handle "${fileHandleOrUndefined.name}" from IndexedDB.`;
return;
}
const [fileHandle] = await window.showOpenFilePicker();
await set('file', fileHandle);
pre1.textContent = `Stored file handle for "${fileHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
// Directory handle
button2.addEventListener('click', async () => {
try {
const directoryHandleOrUndefined = await get('directory');
if (directoryHandleOrUndefined) {
pre2.textContent = `Retrieved directroy handle "${directoryHandleOrUndefined.name}" from IndexedDB.`;
return;
}
const directoryHandle = await window.showDirectoryPicker();
await set('directory', directoryHandle);
pre2.textContent = `Stored directory handle for "${directoryHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
Opgeslagen bestands- of directory-handles en machtigingen
Omdat machtigingen niet altijd tussen sessies behouden blijven , moet u controleren of de gebruiker machtigingen voor het bestand of de map heeft verleend met behulp van queryPermission()
. Zo niet, roep dan requestPermission()
aan om deze (opnieuw) aan te vragen. Dit werkt hetzelfde voor bestands- en maphandles. U moet respectievelijk fileOrDirectoryHandle.requestPermission(descriptor)
of fileOrDirectoryHandle.queryPermission(descriptor)
uitvoeren.
In de teksteditor heb ik een verifyPermission()
methode gemaakt die controleert of de gebruiker al toestemming heeft verleend en, indien nodig, de aanvraag indient.
async function verifyPermission(fileHandle, readWrite) {
const options = {};
if (readWrite) {
options.mode = 'readwrite';
}
// Check if permission was already granted. If so, return true.
if ((await fileHandle.queryPermission(options)) === 'granted') {
return true;
}
// Request permission. If the user grants permission, return true.
if ((await fileHandle.requestPermission(options)) === 'granted') {
return true;
}
// The user didn't grant permission, so return false.
return false;
}
Door schrijfrechten aan te vragen bij de leesaanvraag, kon ik het aantal toestemmingvragen beperken. Bij het openen van het bestand ziet de gebruiker één vraag en verleent toestemming om zowel te lezen als te schrijven.
Een directory openen en de inhoud ervan opsommen
Om alle bestanden in een directory te inventariseren, roept u showDirectoryPicker()
aan. De gebruiker selecteert een directory in een selector, waarna een FileSystemDirectoryHandle
wordt geretourneerd, waarmee u de bestanden in de directory kunt inventariseren en openen. Standaard heeft u leestoegang tot de bestanden in de directory, maar als u schrijftoegang nodig hebt, kunt u { mode: 'readwrite' }
aan de methode doorgeven.
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
for await (const entry of dirHandle.values()) {
console.log(entry.kind, entry.name);
}
});
Als u daarnaast ook nog eens toegang tot elk bestand nodig hebt met behulp van getFile()
om bijvoorbeeld de individuele bestandsgroottes op te vragen, moet u niet opeenvolgend await
op elk resultaat, maar alle bestanden parallel verwerken, bijvoorbeeld met behulp van Promise.all()
.
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
const promises = [];
for await (const entry of dirHandle.values()) {
if (entry.kind !== 'file') {
continue;
}
promises.push(entry.getFile().then((file) => `${file.name} (${file.size})`));
}
console.log(await Promise.all(promises));
});
Bestanden en mappen in een directory maken of openen
Vanuit een directory kunt u bestanden en mappen aanmaken of openen met behulp van de methode getFileHandle()
of getDirectoryHandle()
. Door een optioneel options
met de sleutel create
en de booleaanse waarde true
of false
door te geven, kunt u bepalen of er een nieuw bestand of een nieuwe map moet worden aangemaakt als deze nog niet bestaat.
// In an existing directory, create a new directory named "My Documents".
const newDirectoryHandle = await existingDirectoryHandle.getDirectoryHandle('My Documents', {
create: true,
});
// In this new directory, create a file named "My Notes.txt".
const newFileHandle = await newDirectoryHandle.getFileHandle('My Notes.txt', { create: true });
Het pad van een item in een directory oplossen
Bij het werken met bestanden of mappen in een directory kan het handig zijn om het pad van het betreffende item te achterhalen. Dit kan met de toepasselijk genaamde methode resolve()
. Voor het achterhalen van de oorzaak kan het item een direct of indirect onderliggend item van de directory zijn.
// Resolve the path of the previously created file called "My Notes.txt".
const path = await newDirectoryHandle.resolve(newFileHandle);
// `path` is now ["My Documents", "My Notes.txt"]
Bestanden en mappen in een map verwijderen
Als u toegang hebt verkregen tot een directory, kunt u de bestanden en mappen erin verwijderen met de removeEntry()
methode. Voor mappen kan het verwijderen optioneel recursief zijn en alle submappen en de daarin aanwezige bestanden omvatten.
// Delete a file.
await directoryHandle.removeEntry('Abandoned Projects.txt');
// Recursively delete a folder.
await directoryHandle.removeEntry('Old Stuff', { recursive: true });
Een bestand of map rechtstreeks verwijderen
Als u toegang hebt tot een bestands- of directory-handle, roept u remove()
aan op een FileSystemFileHandle
of FileSystemDirectoryHandle
om deze te verwijderen.
// Delete a file.
await fileHandle.remove();
// Delete a directory.
await directoryHandle.remove();
Bestanden en mappen hernoemen en verplaatsen
Bestanden en mappen kunnen worden hernoemd of verplaatst naar een nieuwe locatie door move()
aan te roepen op de FileSystemHandle
interface. FileSystemHandle
heeft de onderliggende interfaces FileSystemFileHandle
en FileSystemDirectoryHandle
. De move()
methode accepteert één of twee parameters. De eerste kan een string met de nieuwe naam zijn of een FileSystemDirectoryHandle
naar de doelmap. In het laatste geval is de optionele tweede parameter een string met de nieuwe naam, zodat verplaatsen en hernoemen in één stap kan gebeuren.
// Rename the file.
await file.move('new_name');
// Move the file to a new directory.
await file.move(directory);
// Move the file to a new directory and rename it.
await file.move(directory, 'newer_name');
Integratie met slepen en neerzetten
De HTML Drag and Drop-interfaces stellen webapplicaties in staat om gesleepte en neergezette bestanden op een webpagina te accepteren. Tijdens een drag and drop-bewerking worden gesleepte bestands- en directory-items respectievelijk gekoppeld aan bestandsitems en directory-items. De DataTransferItem.getAsFileSystemHandle()
-methode retourneert een promise met een FileSystemFileHandle
-object als het gesleepte item een bestand is, en een promise met een FileSystemDirectoryHandle
-object als het gesleepte item een directory is. De volgende tabel laat dit in de praktijk zien. Merk op dat de DataTransferItem.kind
van de Drag and Drop-interface "file"
is voor zowel bestanden als directory's, terwijl FileSystemHandle.kind
van de File System Access API "file"
is voor bestanden en "directory"
voor directory's.
elem.addEventListener('dragover', (e) => {
// Prevent navigation.
e.preventDefault();
});
elem.addEventListener('drop', async (e) => {
e.preventDefault();
const fileHandlesPromises = [...e.dataTransfer.items]
.filter((item) => item.kind === 'file')
.map((item) => item.getAsFileSystemHandle());
for await (const handle of fileHandlesPromises) {
if (handle.kind === 'directory') {
console.log(`Directory: ${handle.name}`);
} else {
console.log(`File: ${handle.name}`);
}
}
});
Toegang krijgen tot het oorspronkelijke privébestandssysteem
Het private bestandssysteem van de oorsprong is een opslageindpunt dat, zoals de naam al doet vermoeden, privé is ten opzichte van de oorsprong van de pagina. Hoewel browsers dit doorgaans implementeren door de inhoud van dit private bestandssysteem ergens op schijf op te slaan, is het niet de bedoeling dat de inhoud toegankelijk is voor de gebruiker. Evenmin wordt verwacht dat er bestanden of mappen bestaan met namen die overeenkomen met de namen van onderliggende bestanden van het private bestandssysteem van de oorsprong. Hoewel de browser het misschien doet lijken alsof er bestanden zijn, kan de browser deze "bestanden" intern opslaan in een database of een andere datastructuur – aangezien dit een private bestandssysteem van de oorsprong is. Kortom, als u deze API gebruikt, verwacht dan niet dat de aangemaakte bestanden ergens op de harde schijf één-op-één overeenkomen. U kunt zoals gebruikelijk werken op het private bestandssysteem van de oorsprong zodra u toegang hebt tot de root FileSystemDirectoryHandle
.
const root = await navigator.storage.getDirectory();
// Create a new file handle.
const fileHandle = await root.getFileHandle('Untitled.txt', { create: true });
// Create a new directory handle.
const dirHandle = await root.getDirectoryHandle('New Folder', { create: true });
// Recursively remove a directory.
await root.removeEntry('Old Stuff', { recursive: true });
Toegang tot bestanden die zijn geoptimaliseerd voor prestaties vanuit het oorspronkelijke privébestandssysteem
Het oorspronkelijke private bestandssysteem biedt optionele toegang tot een speciaal type bestand dat sterk geoptimaliseerd is voor prestaties, bijvoorbeeld door in-place en exclusieve schrijftoegang tot de inhoud van een bestand te bieden. In Chromium 102 en hoger is er een extra methode op het oorspronkelijke private bestandssysteem om de toegang tot bestanden te vereenvoudigen: createSyncAccessHandle()
(voor synchrone lees- en schrijfbewerkingen). Deze methode is beschikbaar op FileSystemFileHandle
, maar uitsluitend in Web Workers .
// (Read and write operations are synchronous,
// but obtaining the handle is asynchronous.)
// Synchronous access exclusively in Worker contexts.
const accessHandle = await fileHandle.createSyncAccessHandle();
const writtenBytes = accessHandle.write(buffer);
const readBytes = accessHandle.read(buffer, { at: 1 });
Polyfilling
Het is niet mogelijk om de File System Access API-methoden volledig te polyvullen.
- De
showOpenFilePicker()
methode kan worden benaderd met een<input type="file">
element. - De methode
showSaveFilePicker()
kan worden gesimuleerd met een<a download="file_name">
-element. Dit activeert echter een programmatische download en staat niet toe dat bestaande bestanden worden overschreven. - De
showDirectoryPicker()
methode kan enigszins worden nagebootst met het niet-standaardelement<input type="file" webkitdirectory>
.
We hebben een bibliotheek ontwikkeld met de naam browser-fs-access die waar mogelijk gebruikmaakt van de File System Access API en in alle andere gevallen terugvalt op deze op één na beste opties.
Beveiliging en machtigingen
Het Chrome-team heeft de File System Access API ontworpen en geïmplementeerd op basis van de kernprincipes die zijn gedefinieerd in Controlling Access to Powerful Web Platform Features , waaronder gebruikerscontrole en transparantie en gebruikersergonomie.
Een bestand openen of een nieuw bestand opslaan

Bij het openen van een bestand geeft de gebruiker toestemming om een bestand of map te lezen met behulp van de bestandskiezer. De bestandskiezer kan alleen worden weergegeven met een gebruikersgebaar wanneer deze wordt bediend vanuit een beveiligde context . Als gebruikers van gedachten veranderen, kunnen ze de selectie in de bestandskiezer annuleren en krijgt de site geen toegang meer. Dit is hetzelfde gedrag als dat van het element <input type="file">
.

Op dezelfde manier toont de browser de bestandskiezer wanneer een webapp een nieuw bestand wil opslaan. Hiermee kan de gebruiker de naam en locatie van het nieuwe bestand opgeven. Omdat er een nieuw bestand op het apparaat wordt opgeslagen (in plaats van een bestaand bestand te overschrijven), geeft de bestandskiezer de app toestemming om naar het bestand te schrijven.
Beperkte mappen
Om gebruikers en hun gegevens te beschermen, kan de browser de mogelijkheid van de gebruiker om in bepaalde mappen op te slaan beperken, bijvoorbeeld mappen van het kernbesturingssysteem zoals Windows of de bibliotheekmappen van macOS. Wanneer dit gebeurt, toont de browser een prompt en vraagt de gebruiker om een andere map te kiezen.
Een bestaand bestand of map wijzigen
Een webapplicatie kan een bestand op schijf niet wijzigen zonder expliciete toestemming van de gebruiker.
Toestemmingsprompt
Als iemand wijzigingen wil opslaan in een bestand waarvoor hij/zij eerder leestoegang heeft verleend, toont de browser een toestemmingsverzoek waarin toestemming wordt gevraagd aan de site om wijzigingen naar schijf te schrijven. Het toestemmingsverzoek kan alleen worden geactiveerd door een gebruikersgebaar, bijvoorbeeld door op de knop Opslaan te klikken.

Een webapplicatie die meerdere bestanden bewerkt, zoals een IDE, kan ook bij het openen om toestemming vragen om de wijzigingen op te slaan.
Als de gebruiker Annuleren kiest en geen schrijftoegang verleent, kan de webapp geen wijzigingen in het lokale bestand opslaan. De webapp moet de gebruiker een alternatieve methode bieden om zijn gegevens op te slaan, bijvoorbeeld door het bestand te 'downloaden' of door gegevens in de cloud op te slaan.
Transparantie

Zodra een gebruiker toestemming heeft gegeven aan een webapp om een lokaal bestand op te slaan, toont de browser een pictogram in de adresbalk. Door op het pictogram te klikken, wordt een pop-up geopend met een lijst met bestanden waartoe de gebruiker toegang heeft gegeven. De gebruiker kan die toegang altijd weer intrekken.
Permissiepersistentie
De webapp kan wijzigingen in het bestand blijven opslaan zonder dat u hierom wordt gevraagd totdat alle tabbladen van de bron zijn gesloten. Zodra een tabblad is gesloten, verliest de site alle toegang. De volgende keer dat de gebruiker de webapp gebruikt, wordt hij of zij opnieuw gevraagd om toegang tot de bestanden.
Feedback
Wij willen graag uw ervaringen met de File System Access API horen.
Vertel ons over het API-ontwerp
Werkt er iets aan de API dat niet werkt zoals u had verwacht? Of ontbreken er methoden of eigenschappen die u nodig hebt om uw idee te implementeren? Heeft u een vraag of opmerking over het beveiligingsmodel?
- Dien een spec-probleem in op de WICG File System Access GitHub-repository of voeg uw mening toe over een bestaand probleem.
Probleem met de implementatie?
Heb je een bug gevonden in de implementatie van Chrome? Of wijkt de implementatie af van de specificatie?
- Meld een bug op https://new.crbug.com . Zorg ervoor dat u zoveel mogelijk details en instructies voor reproductie verstrekt en stel Components in op
Blink>Storage>FileSystem
.
Wilt u de API gebruiken?
Bent u van plan de File System Access API op uw site te gebruiken? Uw publieke steun helpt ons om functies te prioriteren en laat andere browserleveranciers zien hoe belangrijk het is om deze te ondersteunen.
- Deel hoe u van plan bent het te gebruiken in de WICG Discourse-thread .
- Stuur een tweet naar @ChromiumDev met de hashtag
#FileSystemAccess
en laat ons weten waar en hoe je het gebruikt.
Nuttige links
- Publieke uitleg
- Specificatie voor bestandssysteemtoegang en bestandsspecificatie
- Tracking-bug
- ChromeStatus.com-vermelding
- TypeScript-definities
- API voor toegang tot bestandssysteem - Chromium-beveiligingsmodel
- Blink-component:
Blink>Storage>FileSystem
Dankbetuigingen
De File System Access API-specificatie is geschreven door Marijn Kruisselbrink .