Signatur
Beschreibung
Das StorageManager-Interface ist Teil des Storage Standard der WHATWG. Du erreichst es nicht über einen Konstruktor, sondern über die Singleton-Instanz navigator.storage (im Fenster- und im Worker-Kontext). Es fasst alle clientseitigen Speichermechanismen eines Origins zusammen: IndexedDB, Cache API, Service-Worker-Registrierungen und das Origin Private File System (OPFS).
Die wichtigsten Methoden:
estimate()– liefert einPromise<StorageEstimate>mitusage(belegte Bytes) undquota(zulässige Bytes). So kannst du prüfen, ob noch Platz für große Downloads oder Offline-Daten da ist.persist()– bittet den Browser, den Speicher des Origins als persistent zu markieren. Solcher Speicher wird bei Speicherknappheit nicht automatisch gelöscht. Rückgabewert:Promise<boolean>.persisted()– prüft, ob schon persistenter Speicher gewährt wurde (Promise<boolean>).getDirectory()– gibt einPromise<FileSystemDirectoryHandle>auf das Wurzelverzeichnis des Origin Private File System zurück.
Du brauchst StorageManager vor allem in Offline-first-Anwendungen und PWAs, die viele Daten lokal ablegen (Medien, Kartenkacheln, Dokumente). Ohne Persistenz gilt der Speicher als best effort: Der Browser darf ihn bei Platzmangel nach einer LRU-Strategie ohne Rückfrage löschen.
Alle Methoden stehen nur in einem sicheren Kontext (HTTPS oder localhost) zur Verfügung und arbeiten asynchron.
Rückgabewert
navigator.storage – eine Instanz pro Kontext (Fenster oder Worker). Es gibt keinen öffentlichen Konstruktor.Beispiele
Belegten und verfügbaren Speicher anzeigen
const formatMB = (bytes) => `${(bytes / 1024 / 1024).toFixed(1)} MB`;
const zeigeSpeicher = async () => {
if (!navigator.storage?.estimate) {
console.warn('StorageManager.estimate() wird nicht unterstützt');
return;
}
const { usage, quota } = await navigator.storage.estimate();
const prozent = ((usage / quota) * 100).toFixed(2);
console.log(`Belegt: ${formatMB(usage)} von ${formatMB(quota)} (${prozent} %)`);
};
zeigeSpeicher();
Persistenten Speicher anfordern (PWA mit Offline-Daten)
const sichereSpeicher = async () => {
if (!navigator.storage?.persist) return false;
// Zuerst prüfen, ob schon persistenter Speicher gewährt wurde
if (await navigator.storage.persisted()) {
console.log('Speicher ist bereits persistent.');
return true;
}
const gewaehrt = await navigator.storage.persist();
console.log(gewaehrt
? 'Persistenter Speicher gewährt – Daten werden nicht automatisch gelöscht.'
: 'Abgelehnt – Speicher bleibt "best effort".');
return gewaehrt;
};
// Am besten nach einer Nutzeraktion aufrufen, z. B. "Offline verfügbar machen"
document.querySelector('#offline-btn')?.addEventListener('click', sichereSpeicher);
Vor großem Download freien Platz prüfen
const hatGenugPlatz = async (benoetigteBytes) => {
const { usage = 0, quota = 0 } = await navigator.storage.estimate();
return quota - usage > benoetigteBytes * 1.1; // 10 % Puffer
};
const ladeOfflinePaket = async (url, groesse) => {
if (!(await hatGenugPlatz(groesse))) {
console.error('Nicht genug Speicher für das Offline-Paket.');
return;
}
const cache = await caches.open('offline-v1');
await cache.add(url);
console.log('Paket gespeichert.');
};
ladeOfflinePaket('/karten/region-nord.pbf', 50 * 1024 * 1024);
Datei im Origin Private File System (OPFS) anlegen
const speichereNotiz = async (text) => {
const root = await navigator.storage.getDirectory();
const datei = await root.getFileHandle('notiz.txt', { create: true });
const writable = await datei.createWritable();
await writable.write(text);
await writable.close();
const inhalt = await (await datei.getFile()).text();
console.log('Gelesen:', inhalt);
};
speichereNotiz('Einkaufsliste: Milch, Brot');
// Wichtig · Fallstricke
- Nur Schätzwerte:
estimate()liefert absichtlich ungenaue Werte (z. B. durch Padding bei opaken Cache-Antworten), damit Origins keine Daten über andere Origins oder das System ausspähen können.quotaist nicht der freie Festplattenplatz. - Nur sicherer Kontext:
navigator.storagegibt es nur unter HTTPS oderlocalhost. Prüfe die Unterstützung vorher, z. B. mitnavigator.storage?.persist. - persist() je nach Browser: Chromium entscheidet nach Heuristiken (Engagement, Lesezeichen, installierte PWA, Benachrichtigungsberechtigung) und zeigt keinen Dialog. Firefox fragt den Nutzer mit einem Dialog. Safari gewährt Persistenz nur eingeschränkt. Rechne immer damit, dass
falsezurückkommt. - Safari/ITP: Ohne Persistenz kann Safari Skript-schreibbaren Speicher nach 7 Tagen ohne Nutzerinteraktion löschen.
- Auch persistenter Speicher lässt sich vom Nutzer löschen, etwa über die Browsereinstellungen. Sichere wichtige Daten deshalb zusätzlich auf dem Server.
- Das nicht standardisierte Feld
usageDetailsinStorageEstimategibt es nur in Chromium. Verlass dich nicht darauf. - Wird die Quote überschritten, werfen Schreibvorgänge einen
QuotaExceededError(DOMException). Fang diesen Fehler ab.