CacheStorage
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018.
Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.
Hinweis: Diese Funktion ist in Web Workers verfügbar.
Das CacheStorage
-Interface repräsentiert den Speicher für Cache
-Objekte.
Das Interface:
- Bietet ein Hauptverzeichnis aller benannten Caches, die von einem
ServiceWorker
oder einem anderen Typ von Worker oderwindow
-Scope zugegriffen werden können (Sie sind nicht darauf beschränkt, es nur mit Servicearbeitern zu verwenden). - Pflegt eine Zuordnung von Zeichenfolgen-Namen zu entsprechenden
Cache
-Objekten.
Verwenden Sie CacheStorage.open()
, um eine Cache
-Instanz zu erhalten.
Verwenden Sie CacheStorage.match()
, um zu überprüfen, ob eine gegebene Request
ein Schlüssel in einem der Cache
-Objekte ist, die das CacheStorage
-Objekt verfolgt.
Sie können auf CacheStorage
über die Window.caches
-Eigenschaft in Fenstern oder über die WorkerGlobalScope.caches
-Eigenschaft in Arbeitern zugreifen.
Hinweis:>CacheStorage
lehnt immer mit einem SecurityError
bei nicht vertrauenswürdigen Quellen ab (d.h. solchen, die kein HTTPS verwenden, obwohl diese Definition in Zukunft wahrscheinlich komplexer wird). Beim Testen auf Firefox können Sie dies umgehen, indem Sie die Option Enable Service Workers over HTTP (when toolbox is open) im Firefox DevTools-Options-/Zahnradmenü aktivieren. Außerdem kann CacheStorage
, da es Dateisystemzugriff erfordert, im privaten Modus in Firefox möglicherweise nicht verfügbar sein.
Hinweis:>CacheStorage.match()
ist eine Komfortmethode. Eine gleichwertige Funktionalität zum Abgleichen eines Cache-Eintrags kann implementiert werden, indem ein Array von Cachenamen aus CacheStorage.keys()
zurückgegeben wird, jeder Cache mit CacheStorage.open()
geöffnet wird und der gewünschte mit Cache.match()
abgeglichen wird.
Instanzmethoden
CacheStorage.match()
-
Überprüft, ob eine gegebene
Request
ein Schlüssel in einem derCache
-Objekte ist, die dasCacheStorage
-Objekt verfolgt, und gibt einPromise
zurück, das sich zu diesem Treffer auflöst. CacheStorage.has()
-
Gibt ein
Promise
zurück, das sich zutrue
auflöst, wenn einCache
-Objekt, das demcacheName
entspricht, existiert. CacheStorage.open()
-
Gibt ein
Promise
zurück, das sich zu demCache
-Objekt auflöst, das demcacheName
entspricht (ein neuer Cache wird erstellt, wenn er noch nicht existiert). CacheStorage.delete()
-
Findet das
Cache
-Objekt, das demcacheName
entspricht, und löscht es, falls gefunden, und gibt einPromise
zurück, das sich zutrue
auflöst. Wenn keinCache
-Objekt gefunden wird, löst es sich zufalse
auf. CacheStorage.keys()
-
Gibt ein
Promise
zurück, das sich mit einem Array auflöst, das Zeichenfolgen enthält, die allen benanntenCache
-Objekten entsprechen, die vomCacheStorage
verfolgt werden. Verwenden Sie diese Methode, um über eine Liste allerCache
-Objekte zu iterieren.
Beispiele
Dieses Codebeispiel stammt aus dem MDN einfachen Service Worker-Beispiel (siehe einfacher Service Worker im Livebetrieb.)
Dieses Service Worker-Skript wartet auf ein install
-Ereignis und führt dann waitUntil
aus, um den Installationsprozess für die App zu handhaben. Dies besteht darin, CacheStorage.open
aufzurufen, um einen neuen Cache zu erstellen, und dann Cache.addAll
zu verwenden, um eine Reihe von Assets hinzuzufügen.
Im zweiten Codeblock warten wir, bis ein FetchEvent
ausgelöst wird. Wir konstruieren eine benutzerdefinierte Antwort wie folgt:
- Überprüfen, ob ein Treffer für die Anfrage im CacheStorage gefunden wird. Falls ja, wird dieser verwendet.
- Falls nicht, wird die Anfrage aus dem Netzwerk geholt, dann wird auch der im ersten Block erstellte Cache geöffnet und ein Klon der Anfrage mit
Cache.put
hinzugefügt (cache.put(event.request, response.clone())
). - Wenn dies fehlschlägt (z.B. weil das Netzwerk ausgefallen ist), wird eine Fallback-Antwort zurückgegeben.
Abschließend wird die benutzerdefinierte Antwort, was auch immer sie letztendlich entspricht, unter Verwendung von FetchEvent.respondWith
zurückgegeben.
self.addEventListener("install", (event) => {
event.waitUntil(
caches
.open("v1")
.then((cache) =>
cache.addAll([
"/",
"/index.html",
"/style.css",
"/app.js",
"/image-list.js",
"/star-wars-logo.jpg",
"/gallery/bountyHunters.jpg",
"/gallery/myLittleVader.jpg",
"/gallery/snowTroopers.jpg",
]),
),
);
});
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
// caches.match() always resolves
// but in case of success response will have value
if (response !== undefined) {
return response;
}
return fetch(event.request)
.then((response) => {
// response may be used only once
// we need to save clone to put one copy in cache
// and serve second one
let responseClone = response.clone();
caches
.open("v1")
.then((cache) => cache.put(event.request, responseClone));
return response;
})
.catch(() => caches.match("/gallery/myLittleVader.jpg"));
}),
);
});
Dieses Snippet zeigt, wie die API außerhalb eines Service Worker-Kontextes verwendet werden kann und verwendet den await
-Operator für wesentlich lesbareren Code.
// Try to get data from the cache, but fall back to fetching it live.
async function getData() {
const cacheVersion = 1;
const cacheName = `myapp-${cacheVersion}`;
const url = "https://jsonplaceholder.typicode.com/todos/1";
let cachedData = await getCachedData(cacheName, url);
if (cachedData) {
console.log("Retrieved cached data");
return cachedData;
}
console.log("Fetching fresh data");
const cacheStorage = await caches.open(cacheName);
await cacheStorage.add(url);
cachedData = await getCachedData(cacheName, url);
await deleteOldCaches(cacheName);
return cachedData;
}
// Get data from the cache.
async function getCachedData(cacheName, url) {
const cacheStorage = await caches.open(cacheName);
const cachedResponse = await cacheStorage.match(url);
if (!cachedResponse || !cachedResponse.ok) {
return false;
}
return await cachedResponse.json();
}
// Delete any old caches to respect user's disk space.
async function deleteOldCaches(currentCache) {
const keys = await caches.keys();
for (const key of keys) {
const isOurCache = key.startsWith("myapp-");
if (currentCache === key || !isOurCache) {
continue;
}
caches.delete(key);
}
}
try {
const data = await getData();
console.log({ data });
} catch (error) {
console.error({ error });
}
Spezifikationen
Specification |
---|
Service Workers # cachestorage-interface |