Die Cache API: Eine Kurzanleitung

Hier erfahren Sie, wie Sie mit der Cache API Ihre Anwendungsdaten offline verfügbar machen.

Die Cache API ist ein System zum Speichern und Abrufen von Netzwerkanfragen und der entsprechenden Antworten. Dabei kann es sich um reguläre Anfragen und Antworten handeln, die während der Ausführung Ihrer Anwendung erstellt werden, oder um Daten ausschließlich zum Speichern von Daten für eine spätere Verwendung zu erstellen.

Die Cache API wurde erstellt, damit Service Worker Netzwerkanfragen im Cache speichern können, um unabhängig von der 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 Eigenschaft caches freigegeben, sodass Sie das Vorhandensein der API mit einer einfachen Funktionserkennung testen können:

const cacheAvailable = 'caches' in self;

Unterstützte Browser

  • 40
  • 16
  • 41
  • 11.1

Quelle

Auf die Cache API kann von einem Fenster, iFrame, Worker oder Service Worker aus zugegriffen werden.

Was kann gespeichert werden?

In den Caches werden nur Paare von Request- und Response-Objekten gespeichert, die jeweils HTTP-Anfragen bzw. -Antworten darstellen. Die Anfragen und Antworten können jedoch beliebige Daten enthalten, die über HTTP übertragen werden können.

Wie viel können gespeichert werden?

Kurz gesagt, unverzüglich, mindestens einige hundert Megabyte und potenziell mehrere hundert Gigabyte oder mehr. Browserimplementierungen variieren, aber der verfügbare Speicherplatz richtet sich in der Regel nach der Menge des auf dem Gerät verfügbaren Speichers.

Cache erstellen und öffnen

Verwenden Sie zum Öffnen eines Cache die Methode caches.open(name) und übergeben Sie den Namen des Cache als einzelnen Parameter. Wenn der benannte Cache nicht vorhanden ist, wird er erstellt. Diese Methode gibt einen Promise zurück, der mit dem Cache-Objekt aufgelöst wird.

const cache = await caches.open('my-cache');
// do something with cache...

Zu Cache hinzufügen

Es gibt drei Möglichkeiten, einem Cache ein Element hinzuzufügen: add, addAll und put. Alle drei Methoden geben Promise zurück.

cache.add

Zuerst gibt es cache.add(). Sie verwendet einen Parameter, entweder einen Request oder eine URL (string), stellt eine Anfrage an das Netzwerk und speichert die Antwort im Cache. Wenn der Abruf fehlschlägt oder der Statuscode der Antwort nicht im Bereich 200 liegt, wird nichts gespeichert und Promise lehnt ab. Beachten Sie, dass ursprungsübergreifende Anfragen, die nicht im CORS-Modus sind, nicht gespeichert werden können, da sie das status-Objekt 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 kommt cache.addAll(). Sie funktioniert ähnlich wie add(), verwendet jedoch ein Array aus Request-Objekten oder URLs (strings). Das funktioniert ähnlich wie das 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 werden übereinstimmende Einträge durch einen neuen Eintrag überschrieben. Es werden die gleichen Abgleichsregeln verwendet, die im Abschnitt retrieving beschrieben sind.

cache.put

Schließlich gibt es noch cache.put(), mit dem Sie entweder eine Antwort aus dem Netzwerk speichern oder Ihre eigene Response erstellen und speichern können. Dafür sind zwei Parameter erforderlich. Das erste kann entweder ein Request-Objekt oder eine URL (string) sein. Die zweite muss ein Response sein, entweder aus dem Netzwerk oder durch Ihren 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 Methode put() ist großzügiger als add() oder addAll(). Damit können Sie Nicht-CORS-Antworten oder andere Antworten speichern, bei denen der Statuscode der Antwort nicht im Bereich 200 liegt. Alle vorherigen Antworten für dieselbe Anfrage werden überschrieben.

Anfrageobjekte erstellen

Erstellen Sie das Request-Objekt mit einer URL für das gespeicherte Objekt:

const request = new Request('/my-data-store/item-id');

Mit Antwortobjekten arbeiten

Der Response-Objektkonstruktor akzeptiert viele Datentypen, einschließlich Blob-, ArrayBuffer-, FormData-Objekten und Strings.

const imageBlob = new Blob([data], {type: 'image/jpeg'});
const imageResponse = new Response(imageBlob);
const stringResponse = new Response('Hello world');

Du kannst den MIME-Typ von Response festlegen, indem du den entsprechenden Header festlegst.

  const options = {
    headers: {
      'Content-Type': 'application/json'
    }
  }
  const jsonResponse = new Response('{}', options);

Wenn Sie einen Response abgerufen haben und auf seinen Text zugreifen möchten, gibt es mehrere Hilfsmethoden. Jedes gibt einen Promise zurück, der mit einem Wert eines anderen Typs aufgelöst wird.

Methode Beschreibung
arrayBuffer Gibt einen ArrayBuffer zurück, der den Text in Byte enthält.
blob Gibt Blob zurück. Wenn die Response mit einer Blob erstellt wurde, hat die neue Blob denselben Typ. Andernfalls wird Content-Type von Response verwendet.
text Interpretiert die Bytes des Textes als UTF-8-codierten String.
json Interpretiert die Bytes des Texts als UTF-8-codierten String und versucht dann, ihn als JSON zu parsen. Gibt das resultierende Objekt zurück oder gibt TypeError aus, wenn der String nicht als JSON geparst werden kann.
formData Interpretiert die Byte 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 gibt ein TypeError aus, wenn die Daten nicht geparst werden können.
body Gibt einen ReadableStream für die Textdaten 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]

Daten aus einem Cache abrufen

Zum Suchen eines Elements in einem Cache können Sie die Methode match verwenden.

const response = await cache.match(request);
console.log(request, response);

Wenn request ein String ist, konvertiert der Browser ihn durch Aufrufen von new Request(request) in einen Request-Wert. Die Funktion gibt ein Promise zurück, das in einen Response aufgelöst wird, wenn ein übereinstimmender Eintrag gefunden wird, oder 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 Optionsobjekt 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 mehr als eine im Cache gespeicherte Anfrage übereinstimmt, wird die zuerst erstellte Anfrage 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.`);

Sie können aber auch mit caches.match() in allen Caches gleichzeitig suchen, anstatt cache.match() für jeden Cache aufzurufen.

Suchen

Die Cache API bietet keine Möglichkeit, nach Anfragen oder Antworten zu suchen, außer zum Abgleich von Einträgen mit einem Response-Objekt. Sie können jedoch mithilfe von Filtern oder durch Erstellen eines Index Ihre eigene Suche implementieren.

Wird gefiltert

Eine Möglichkeit, Ihre eigene Suche zu implementieren, besteht darin, alle Einträge zu iterieren und nach den gewünschten Einträgen zu filtern. Angenommen, Sie möchten alle Elemente finden, deren URLs 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 ein beliebiges Attribut der Objekte Request und Response verwenden, um die Einträge zu filtern. Dies ist bei einer Suche in großen Datenmengen langsam.

Index erstellen

Die andere Möglichkeit, Ihre eigene Suche zu implementieren, besteht darin, einen separaten Index mit Einträgen, die durchsucht werden können, zu verwalten und den Index in IndexedDB zu speichern. Da dieser Vorgang für IndexedDB entwickelt wurde, bietet er bei einer großen Anzahl von Einträgen eine viel bessere Leistung.

Wenn du die URL von Request zusammen mit den suchbaren Eigenschaften speicherst, kannst du nach der Suche ganz einfach den korrekten Cache-Eintrag abrufen.

Elemente löschen

So löschen Sie ein Element aus einem Cache:

cache.delete(request);

Dabei kann die Anfrage ein Request- oder URL-String sein. Bei dieser Methode wird auch dasselbe Optionsobjekt wie cache.match verwendet, sodass Sie mehrere Request/Response-Paare für dieselbe URL löschen können.

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 in true aufgelöst wird, wenn der Cache vorhanden war und gelöscht wurde, oder in einen anderen Wert, false.

Vielen Dank

Vielen Dank an Mat Scales, der die Originalversion dieses Artikels geschrieben hat, der erstmals auf WebFundamentals erschienen ist.