Die Cache API: Eine Kurzanleitung

Erfahren Sie, wie Sie mit der Cache API Anwendungsdaten offline verfügbar machen.

Die Cache API ist ein System zum Speichern und Abrufen von und die zugehörigen Antworten. Das können normale Anfragen sein, und Antworten, die beim Ausführen der Anwendung erstellt wurden. dürfen nur zum Zweck der Speicherung von Daten für eine spätere Verwendung erstellt werden.

Die Cache API wurde erstellt, damit Service Worker Netzwerkanfragen im Cache speichern können sodass sie unabhängig von der Netzwerkgeschwindigkeit Verfügbarkeit. 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. Es ist über das globale Attribut caches bereitgestellt, sodass Sie testen können, der API mit einer einfachen Funktionserkennung:

const cacheAvailable = 'caches' in self;

Unterstützte Browser

  • Chrome: 40. <ph type="x-smartling-placeholder">
  • Edge: 16. <ph type="x-smartling-placeholder">
  • Firefox: 41. <ph type="x-smartling-placeholder">
  • Safari: 11.1 <ph type="x-smartling-placeholder">

Quelle

Auf die Cache API kann über ein Fenster, einen iFrame, einen Worker oder einen Service Worker zugegriffen werden.

Was kann gespeichert werden?

In den Caches werden nur Paare aus Request und Response-Objekte, die HTTP-Anfragen und -Antworten darstellen, . Die Anfragen und Antworten können jedoch beliebige Daten enthalten. der über HTTP übertragen werden kann.

Wie viel kann ich speichern?

Kurz gesagt: Sehr, mindestens ein paar hundert Megabyte und potenziell Hunderte Gigabyte oder mehr. Browserimplementierungen unterscheiden sich, hängt in der Regel davon ab, wie viel Speicherplatz auf dem Gerät.

Cache erstellen und öffnen

Verwenden Sie zum Öffnen eines Cache die Methode caches.open(name) und übergeben Sie den Namen des als einzelnen Parameter. Wenn der benannte Cache nicht vorhanden ist, 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...

Zu einem Cache hinzufügen

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

cache.add

Erstens: cache.add(). Es wird ein Parameter verwendet, entweder ein Request oder eine URL (string). Er sendet eine Anfrage an das Netzwerk und speichert die Antwort. im Cache gespeichert. Wenn die oder wenn der Statuscode der Antwort nicht im Bereich 200 liegt, wird nichts gespeichert und der Promise lehnt ab. Beachten Sie, dass ursprungsübergreifende Anfragen, die nicht im CORS-Modus sind, können nicht gespeichert werden, da sie den folgenden status zurückgeben: 0. 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(), benötigt jedoch einen Array von Request-Objekten oder URLs (strings) Das funktioniert ähnlich wie cache.add für jede einzelne Anfrage aufrufen, außer dass der Promise lehnt ab, wenn eine einzelne Anfrage nicht im Cache gespeichert wird.

const urls = ['/weather/today.json', '/weather/tomorrow.json'];
cache.addAll(urls);

In jedem dieser Fälle überschreibt ein neuer Eintrag alle übereinstimmenden vorhandenen Einträge. Dabei werden dieselben Zuordnungsregeln verwendet, die im Abschnitt Abrufen.

cache.put

Schließlich gibt es cache.put(), mit dem Sie entweder eine Antwort aus dem Netzwerk aus oder erstelle und speichere deine eigene Response. Es sind zwei Parameter. Das erste kann entweder ein Request-Objekt oder eine URL (string) sein. Die zweite muss eine Response sein, die entweder aus dem Netzwerk stammt oder von Ihrem Code.

// 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 entweder add() oder addAll(). können Sie Nicht-CORS-Antworten oder andere Antworten speichern, bei denen der Status Code der Antwort nicht im Bereich 200 liegt. Alle früheren Daten werden überschrieben. Antworten für dieselbe Anfrage.

Anfrageobjekte erstellen

Erstellen Sie das Request-Objekt unter Verwendung einer URL für das zu speichernde Objekt:

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

Mit Antwortobjekten arbeiten

Der Response-Objektkonstruktor akzeptiert viele Datentypen, darunter: Blob-, ArrayBuffer- und 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 eine Response abgerufen haben und auf ihren Text zugreifen möchten, gibt es verschiedene Hilfsmethoden, die Sie verwenden können. Jeder gibt einen Promise zurück, der mit einem Wert eines anderen Typs.

Methode Beschreibung
arrayBuffer Gibt ein ArrayBuffer zurück, das den Text enthält, serialisiert zu Bytes.
blob Gibt Blob zurück. Wenn Response erstellt wurde mit einem Blob hat dieses neue Blob dasselbe Typ. Andernfalls wird der Content-Type des Response wird 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, um sie als JSON zu parsen. Gibt das resultierende Objekt zurück oder wirft eine TypeError, wenn der String nicht als JSON geparst werden kann.
formData Interpretiert die Byte des Textkörpers als HTML-Formular, das entweder als multipart/form-data oder application/x-www-form-urlencoded. Gibt Folgendes zurück: FormData oder ein TypeError-Objekt ausgelöst, wenn die Daten nicht geparst werden können.
body Gibt einen ReadableStream für die Körperdaten.

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

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, konvertiert der Browser ihn in einen Request, indem er Folgendes aufruft: new Request(request) Die Funktion gibt ein Promise zurück, das in einen Response, wenn ein übereinstimmender Eintrag gefunden wird, oder undefined, wenn ein übereinstimmender Eintrag gefunden wird.

Um festzustellen, ob zwei Requests übereinstimmen, verwendet der Browser nicht nur die URL. Zwei Anfragen gelten als unterschiedlich, wenn sie unterschiedliche Abfragestrings haben, Vary-Header oder HTTP-Methoden (GET, POST, PUT usw.).

Sie können einige oder alle dieser Dinge ignorieren, indem Sie ein Optionsobjekt als zweiten Parameter.

const options = {
  ignoreSearch: true,
  ignoreMethod: true,
  ignoreVary: true
};

const response = await cache.match(request, options);
// do something with the response

Wenn mehrere im Cache gespeicherte Anfragen übereinstimmen, wird die zuerst erstellte Anfrage zurückgegeben. Wenn Sie alle übereinstimmenden Antworten abrufen möchten, können Sie cache.matchAll()

const options = {
  ignoreSearch: true,
  ignoreMethod: true,
  ignoreVary: true
};

const responses = await cache.matchAll(request, options);
console.log(`There are ${responses.length} matching responses.`);

Mit caches.match() können Sie außerdem 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 mit Ausnahme von übereinstimmenden Einträgen für ein Response-Objekt. Sie können jedoch Ihre eigene Suche mithilfe von Filtern oder durch Erstellen eines Index implementieren.

Filtern

Eine Möglichkeit zur Implementierung Ihrer eigenen Suche ist die Iteration über alle Einträge und bis zu den gewünschten Filtern. Angenommen, Sie möchten alle Elemente mit URLs, die auf .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;
}

Auf diese Weise können Sie jedes Attribut der Objekte Request und Response für Folgendes verwenden: um die Einträge zu filtern. Beachten Sie, dass dieser Vorgang langsam ist, wenn Sie in einer großen Anzahl von Daten.

Index erstellen

Die andere Möglichkeit zur Implementierung Ihrer eigenen Suche besteht darin, einen separaten Index Einträge, die durchsucht werden können und den Index in IndexedDB speichern. Da dies die Art von Operation, die IndexedDB für sie entwickelt hat, eine viel bessere Leistung mit eine große Anzahl von Einträgen.

Wenn du die URL von Request zusammen mit den durchsuchbaren Properties speicherst können Sie nach der Suche problemlos den richtigen Cache-Eintrag abrufen.

Löschen von Elementen

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 werden auch die gleichen Optionsobjekts wie cache.match, womit Sie mehrere Request/Response-Paare für dieselbe URL

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

Vielen Dank

Vielen Dank an Mat Scales, die die Originalversion dieses Artikels verfasst haben. erstmals bei WebFundamentals.