Informationen zur Verwendung der Cache API, um Ihre Anwendungsdaten offline verfügbar zu machen
Die Cache API ist ein System zum Speichern und Abrufen von Netzwerkanfragen und den entsprechenden Antworten. Dabei kann es sich um reguläre Anfragen und Antworten handeln, die im Rahmen der Ausführung Ihrer Anwendung erstellt werden, oder sie können ausschließlich zum Speichern von Daten für die spätere Verwendung erstellt werden.
Die Cache API wurde entwickelt, damit Service Worker Netzwerkanfragen im Cache speichern können, um unabhängig von Netzwerkgeschwindigkeit oder ‑verfügbarkeit schnelle Antworten zu liefern. Die API kann jedoch auch als allgemeiner Speichermechanismus verwendet werden.
Wo ist der Dienst verfügbar?
Die Cache API ist in allen modernen Browsern verfügbar. Sie wird über die globale caches
-Eigenschaft verfügbar gemacht. Sie können also mit einer einfachen Funktionserkennung prüfen, ob die API vorhanden ist:
const cacheAvailable = 'caches' in self;
Auf die Cache API kann über ein Fenster, ein iFrame, einen Worker oder einen Service Worker zugegriffen werden.
Was kann gespeichert werden?
In den Caches werden nur Paare von Request
- und Response
-Objekten gespeichert, die HTTP-Anfragen bzw. -Antworten darstellen. Die Anfragen und Antworten können jedoch beliebige Daten enthalten, die über HTTP übertragen werden können.
Wie viel kann gespeichert werden?
Kurz gesagt: Viel. Mindestens einige Hundert Megabyte und möglicherweise Hunderte von Gigabyte oder mehr. Die Browserimplementierungen variieren, aber die verfügbare Speichermenge basiert in der Regel auf der Speichermenge, die auf dem Gerät verfügbar ist.
Cache erstellen und öffnen
Verwenden Sie die Methode caches.open(name)
, um einen Cache zu öffnen. Übergeben Sie dazu den Namen des Caches als einzigen Parameter. Wenn der benannte Cache nicht vorhanden ist, wird er erstellt. Diese Methode gibt ein Promise
zurück, das mit dem Cache
-Objekt aufgelöst wird.
const cache = await caches.open('my-cache');
// do something with cache...
Cache hinzufügen
Es gibt drei Möglichkeiten, ein Element in einen Cache aufzunehmen: add
, addAll
und put
.
Alle drei Methoden geben eine Promise
zurück.
cache.add
Zuerst gibt es cache.add()
. Die Funktion hat einen Parameter, entweder Request
oder eine URL (string
). Sie sendet eine Anfrage an das Netzwerk und speichert die Antwort im Cache. Wenn der Abruf fehlschlägt oder der Statuscode der Antwort nicht im 200er-Bereich liegt, wird nichts gespeichert und das Promise
wird abgelehnt. Beachten Sie, dass anfrageübergreifende Anfragen, die nicht im CORS-Modus sind, nicht gespeichert werden können, da sie einen status
von 0
zurückgeben. Solche Anfragen können nur mit put
gespeichert werden.
// Retreive data.json from the server and store the response.
cache.add(new Request('/data.json'));
// Retreive data.json from the server and store the response.
cache.add('/data.json');
cache.addAll
Als Nächstes cache.addAll()
. Sie funktioniert ähnlich wie add()
, verwendet aber ein Array von Request
-Objekten oder URLs (string
s). Das funktioniert ähnlich wie beim Aufrufen von cache.add
für jede einzelne Anfrage, mit der Ausnahme, dass Promise
abgelehnt wird, wenn eine einzelne Anfrage nicht im Cache gespeichert ist.
const urls = ['/weather/today.json', '/weather/tomorrow.json'];
cache.addAll(urls);
In jedem dieser Fälle wird ein übereinstimmender vorhandener Eintrag durch einen neuen Eintrag überschrieben. Dabei werden dieselben Abgleichsregeln verwendet, die im Abschnitt zum Abrufen beschrieben werden.
cache.put
Schließlich gibt es noch cache.put()
, mit dem Sie entweder eine Antwort aus dem Netzwerk speichern oder ein eigenes Response
erstellen und speichern können. Er hat zwei Parameter. Der erste kann entweder ein Request
-Objekt oder eine URL (string
) sein. Der zweite muss ein Response
sein, entweder aus dem Netzwerk oder von Ihrem Code generiert.
// Retrieve data.json from the server and store the response.
cache.put('/data.json');
// Create a new entry for test.json and store the newly created response.
cache.put('/test.json', new Response('{"foo": "bar"}'));
// Retrieve data.json from the 3rd party site and store the response.
cache.put('https://example.com/data.json');
Die put()
-Methode ist toleranter als add()
oder addAll()
. Sie ermöglicht es Ihnen, Nicht-CORS-Antworten oder andere Antworten zu speichern, bei denen der Statuscode der Antwort nicht im 200er-Bereich liegt. Alle vorherigen Antworten auf dieselbe Anfrage werden überschrieben.
Request-Objekte erstellen
Erstellen Sie das Request
-Objekt mit einer URL für das zu speichernde Element:
const request = new Request('/my-data-store/item-id');
Mit Antwortobjekten arbeiten
Der Konstruktor für das Response
-Objekt akzeptiert viele Datentypen, darunter Blob
, ArrayBuffer
, FormData
-Objekte und Strings.
const imageBlob = new Blob([data], {type: 'image/jpeg'});
const imageResponse = new Response(imageBlob);
const stringResponse = new Response('Hello world');
Sie können den MIME-Typ eines Response
festlegen, indem Sie den entsprechenden Header festlegen.
const options = {
headers: {
'Content-Type': 'application/json'
}
}
const jsonResponse = new Response('{}', options);
Wenn Sie ein Response
abgerufen haben und auf seinen Text zugreifen möchten, können Sie verschiedene Hilfsmethoden verwenden. Jede Funktion gibt ein Promise
zurück, das mit einem Wert eines anderen Typs aufgelöst wird.
Methode | Beschreibung |
---|---|
arrayBuffer |
Gibt ein ArrayBuffer -Objekt mit dem in Byte serialisierten Textkörper zurück.
|
blob |
Gibt Blob zurück. Wenn die Response mit einem Blob erstellt wurde, hat dieses neue Blob denselben Typ. Andernfalls wird die Content-Type der Response verwendet.
|
text |
Interpretiert die Byte des Textkörpers als UTF-8-codierten String. |
json |
Interpretiert die Byte des Textkörpers als UTF-8-codierten String und versucht dann, ihn als JSON zu parsen. Gibt das resultierende Objekt zurück oder löst eine TypeError aus, wenn der String nicht als JSON geparst werden kann.
|
formData |
Interpretiert die Bytes des Texts als HTML-Formular, das entweder als multipart/form-data oder application/x-www-form-urlencoded codiert ist. Gibt ein FormData-Objekt zurück oder löst eine TypeError aus, wenn die Daten nicht geparst werden können.
|
body |
Gibt einen ReadableStream für die Body-Daten zurück. |
Beispiel:
const response = new Response('Hello world');
const buffer = await response.arrayBuffer();
console.log(new Uint8Array(buffer));
// Uint8Array(11) [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
Aus einem Cache abrufen
Mit der Methode match
können Sie ein Element in einem Cache suchen.
const response = await cache.match(request);
console.log(request, response);
Wenn request
ein String ist, wird er vom Browser durch Aufrufen von new Request(request)
in einen Request
konvertiert. Die Funktion gibt ein Promise
zurück, das in ein Response
aufgelöst wird, wenn ein übereinstimmender Eintrag gefunden wird, oder andernfalls in undefined
.
Um festzustellen, ob zwei Requests
übereinstimmen, verwendet der Browser mehr als nur die URL. Zwei Anfragen gelten als unterschiedlich, wenn sie unterschiedliche Abfragestrings, Vary
-Header oder HTTP-Methoden (GET
, POST
, PUT
usw.) haben.
Sie können einige oder alle dieser Dinge ignorieren, indem Sie ein Optionenobjekt als zweiten Parameter übergeben.
const options = {
ignoreSearch: true,
ignoreMethod: true,
ignoreVary: true
};
const response = await cache.match(request, options);
// do something with the response
Wenn mehrere zwischengespeicherte Anfragen übereinstimmen, wird die zuerst erstellte zurückgegeben. Wenn Sie alle übereinstimmenden Antworten abrufen möchten, können Sie cache.matchAll()
verwenden.
const options = {
ignoreSearch: true,
ignoreMethod: true,
ignoreVary: true
};
const responses = await cache.matchAll(request, options);
console.log(`There are ${responses.length} matching responses.`);
Als Abkürzung können Sie alle Caches gleichzeitig durchsuchen, indem Sie caches.match()
verwenden, anstatt cache.match()
für jeden Cache aufzurufen.
Recherche
Die Cache API bietet keine Möglichkeit, nach Anfragen oder Antworten zu suchen, außer Einträge mit einem Response
-Objekt abzugleichen. Sie können jedoch eine eigene Suche implementieren, indem Sie filtern oder einen Index erstellen.
Filtern
Eine Möglichkeit, eine eigene Suche zu implementieren, besteht darin, alle Einträge zu durchlaufen und die gewünschten Einträge herauszufiltern. Angenommen, Sie möchten alle Elemente mit URLs finden, die mit .png
enden.
async function findImages() {
// Get a list of all of the caches for this origin
const cacheNames = await caches.keys();
const result = [];
for (const name of cacheNames) {
// Open the cache
const cache = await caches.open(name);
// Get a list of entries. Each item is a Request object
for (const request of await cache.keys()) {
// If the request URL matches, add the response to the result
if (request.url.endsWith('.png')) {
result.push(await cache.match(request));
}
}
}
return result;
}
So können Sie beliebige Attribute der Objekte Request
und Response
verwenden, um die Einträge zu filtern. Hinweis: Bei der Suche in großen Datensätzen kann es zu Verzögerungen kommen.
Index erstellen
Eine andere Möglichkeit, eine eigene Suche zu implementieren, besteht darin, einen separaten Index von Einträgen zu verwalten, die durchsucht werden können, und den Index in IndexedDB zu speichern. Da IndexedDB für diese Art von Vorgang entwickelt wurde, ist die Leistung bei einer großen Anzahl von Einträgen viel besser.
Wenn Sie die URL des Request
zusammen mit den durchsuchbaren Eigenschaften speichern, können Sie den richtigen Cacheeintrag nach der Suche ganz einfach abrufen.
Element löschen
So löschen Sie ein Element aus einem Cache:
cache.delete(request);
Dabei kann „request“ ein Request
oder ein URL-String sein. Diese Methode verwendet dasselbe Optionenobjekt wie cache.match
. So können Sie mehrere Request
-/Response
-Paare für dieselbe URL löschen.
cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});
Cache löschen
Rufen Sie caches.delete(name)
auf, um einen Cache zu löschen. Diese Funktion gibt ein Promise
zurück, das zu true
aufgelöst wird, wenn der Cache vorhanden war und gelöscht wurde, oder zu false
, wenn dies nicht der Fall ist.
Vielen Dank
Vielen Dank an Mat Scales, der die Originalversion dieses Artikels geschrieben hat, die zuerst auf WebFundamentals veröffentlicht wurde.