Signatur
Beschreibung
Ein Cache-Objekt ist ein benannter, dauerhafter Speicher für Paare aus Request und Response. Man erzeugt es nicht selbst. Man öffnet es über caches.open(name). Das globale caches ist ein CacheStorage-Objekt und steht in Fenstern, Web-Workern und vor allem in Service Workern bereit. Der typische Einsatz sind Offline-fähige Webanwendungen (PWAs): Statische Dateien werden beim install-Event vorab in den Cache geladen und im fetch-Event daraus beantwortet.
Die wichtigsten Methoden geben alle ein Promise zurück:
match(request, options): liefert die erste passendeResponseoderundefined.matchAll(request, options): liefert alle passenden Antworten als Array.add(request): lädt die Ressource perfetch()und speichert die Antwort.addAll(requests): wieadd(), aber für mehrere URLs. Es gilt alles oder nichts.put(request, response): speichert ein beliebiges Paar aus Anfrage und Antwort direkt.delete(request, options): entfernt Einträge und lieferttrueoderfalse.keys(request, options): liefert die gespeichertenRequest-Objekte.
Der Browser aktualisiert und löscht Einträge nicht automatisch. HTTP-Header wie Cache-Control oder Expires spielen dafür keine Rolle. Das Aufräumen (Versionierung, Löschen alter Caches) ist Aufgabe der Anwendung. Der Browser kann den gesamten Speicher eines Ursprungs aber verwerfen, wenn der Platz knapp wird. Ob ein Eintrag passt, entscheidet der Abgleich von URL und Methode. Die gemeinsamen options steuern diesen Abgleich:
ignoreSearch: ignoriert den Query-String.ignoreMethod: vergleicht auch bei anderen Methoden als GET.ignoreVary: ignoriert denVary-Header.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $request Pflicht | Request | string | URL | Die Anfrage bzw. URL, nach der gesucht wird oder unter der gespeichert wird (bei match, add, put, delete). Bei matchAll und keys optional. |
|
| $response | Response | Nur bei put(): die zu speichernde Antwort. Ihr Body wird dabei verbraucht. |
|
| $requests | Array<Request | string> | Nur bei addAll(): Liste der zu ladenden und zu speichernden Ressourcen. |
|
| $options | { ignoreSearch?: boolean, ignoreMethod?: boolean, ignoreVary?: boolean } | alle false | Steuert den Abgleich bei match, matchAll, delete und keys. |
Rückgabewert
Promise:match:Responseoderundefined.matchAll:Response[].keys:Request[].delete:boolean.add,addAllundput:undefined.
Beispiele
Cache öffnen und Dateien vorab laden (Service Worker install)
// sw.js
const CACHE_NAME = 'app-v2';
const ASSETS = ['/', '/index.html', '/styles.css', '/app.js', '/logo.svg'];
self.addEventListener('install', (event) => {
event.waitUntil((async () => {
const cache = await caches.open(CACHE_NAME); // liefert ein Cache-Objekt
await cache.addAll(ASSETS); // schlägt komplett fehl, wenn eine URL fehlschlägt
console.log('Vorab geladen:', ASSETS.length, 'Dateien');
})());
});
Zuerst im Cache suchen, sonst übers Netzwerk laden und speichern
self.addEventListener('fetch', (event) => {
if (event.request.method !== 'GET') return;
event.respondWith((async () => {
const cache = await caches.open('app-v2');
const cached = await cache.match(event.request);
if (cached) return cached;
const response = await fetch(event.request);
if (response.ok) {
// clone(), weil der Body nur einmal gelesen werden kann
await cache.put(event.request, response.clone());
}
return response;
})());
});
Einträge auflisten und alte Caches aufräumen
const inspectAndClean = async () => {
const cache = await caches.open('app-v2');
const requests = await cache.keys();
console.log(requests.map((r) => new URL(r.url).pathname));
// Einen Eintrag unabhängig vom Query-String löschen
const removed = await cache.delete('/api/data', { ignoreSearch: true });
console.log('Gelöscht:', removed);
// Alle Caches außer der aktuellen Version entfernen
const names = await caches.keys();
await Promise.all(
names.filter((n) => n !== 'app-v2').map((n) => caches.delete(n))
);
};
inspectAndClean();
// Wichtig · Fallstricke
- Nur in sicheren Kontexten verfügbar (HTTPS oder
localhost). Auf einfachem HTTP istcachesnicht definiert. - Keine automatische Ablaufsteuerung: Einträge bleiben erhalten, bis Ihr Code sie löscht. Versionieren Sie Cache-Namen und räumen Sie im
activate-Event auf. - Body nur einmal lesbar: Wenn eine Antwort gespeichert und zurückgegeben werden soll, speichern Sie eine Kopie mit
response.clone(). add()undaddAll()lehnen das Promise ab, wenn der Server einen Statuscode außerhalb von 200–299 liefert. Beiput()gibt es diese Prüfung nicht. Deshalb vorherresponse.okselbst prüfen.put()mit einer POST-Anfrage wirft einenTypeError. Nur GET-Anfragen lassen sich speichern.- Undurchsichtige Antworten (
no-cors,type: 'opaque') haben den Status 0. Sie belegen im Speicherkontingent oft deutlich mehr Platz als ihre tatsächliche Größe (Chrome rechnet mehrere MB pro Antwort). - Der Speicher ist begrenzt und kann vom Browser geräumt werden. Mit
navigator.storage.estimate()lässt sich der Verbrauch prüfen.navigator.storage.persist()fordert dauerhaften Speicher an. - Sicherheit: Speichern Sie keine personalisierten oder sensiblen Antworten ohne Grund, zum Beispiel Antworten mit Auth-Tokens. Sie bleiben sonst nach dem Logout erhalten, wenn sie nicht gezielt gelöscht werden.