Interfejs Cache API: krótki przewodnik

Dowiedz się, jak używać interfejsu Cache API do udostępniania danych aplikacji offline.

Interfejs Cache API to system do przechowywania i pobierania sieci żądań i odpowiadających im odpowiedzi. Mogą to być zwykłe prośby i odpowiedzi utworzonych w trakcie uruchamiania aplikacji, tworzone wyłącznie w celu przechowywania danych do późniejszego użycia.

Interfejs Cache API został utworzony, aby umożliwić mechanizmom Service Worker buforowanie żądań sieciowych dzięki czemu mogą szybko udzielić odpowiedzi niezależnie od szybkości sieci czy dostępność. Interfejs API może być jednak również używany jako ogólny mechanizm przechowywania danych.

Gdzie jest dostępna?

Interfejs Cache API jest dostępny we wszystkich nowoczesnych przeglądarkach. Jest są udostępniane za pomocą globalnej właściwości caches, więc możesz sprawdzić występowanie interfejs API za pomocą prostego wykrywania funkcji:

const cacheAvailable = 'caches' in self;

Obsługa przeglądarek

  • Chrome: 40
  • Edge: 16.
  • Firefox: 41.
  • Safari: 11.1

Źródło

Interfejs Cache API jest dostępny z poziomu okna, elementu iframe, instancji roboczej lub skryptu service worker.

Co można przechowywać

W pamięci podręcznej przechowywane są tylko pary Request oraz obiekty Response reprezentujące żądania i odpowiedzi HTTP, . Żądania i odpowiedzi mogą jednak zawierać dowolne dane, które można przekazywać przez HTTP.

Ile można przechowywać?

Krótko mówiąc, dużo, przynajmniej kilkaset megabajtów, o wielkości setek gigabajtów lub więcej. Implementacje przeglądarek są różne, ale dostępnego miejsca zależy zwykle od ilości wolnego miejsca urządzenia.

Tworzenie i otwieranie pamięci podręcznej

Aby otworzyć pamięć podręczną, użyj metody caches.open(name), przekazując nazwę pliku pamięci podręcznej jako pojedynczego parametru. Jeśli nazwana pamięć podręczna nie istnieje, jest Utworzono. Ta metoda zwraca błąd Promise, który analizuje obiekt Cache.

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

Dodawanie do pamięci podręcznej

Istnieją 3 sposoby dodawania elementu do pamięci podręcznej: add, addAll i put. Wszystkie 3 metody zwracają Promise.

cache.add

Pierwszy jest cache.add(). Przyjmuje jeden parametr: Request lub adres URL (string). Wysyła żądanie do sieci i zapisuje odpowiedź w pamięci podręcznej. Jeśli nie udało się pobrać lub jeśli kod stanu odpowiedzi nie mieści się w zakresie 200, nic nie jest przechowywane, a Promise odrzuca. Pamiętaj, że zasoby z innych domen żądań spoza trybu CORS nie można przechowywać, ponieważ zwracają one status 0 Takie żądania można przechowywać tylko w usłudze put.

// 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

Następnie jest cache.addAll(). Działa ona podobnie jak add(), ale wymaga tablica Request obiektów lub adresów URL (string). Działa to podobnie jak wywołania funkcji cache.add w przypadku każdego pojedynczego żądania, z tym że Promise odrzuca, jeśli żadne pojedyncze żądanie nie jest przechowywane w pamięci podręcznej.

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

W każdym z tych przypadków nowy wpis zastąpi dowolny pasujący istniejący wpis. Stosowane są te same reguły dopasowania, które są opisane w sekcji pobieram.

cache.put

Ostatnią istotną kwestią jest plik cache.put(), który służy do zapisywania odpowiedzi z sieci lub utworzyć i zapisać własny zasób Response. Potrzeba 2 razy . Pierwszą może być obiekt Request lub adres URL (string). Druga musi być wartością Response, pochodzącą z sieci lub wygenerowaną przez w kodzie.

// 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');

Metoda put() jest bardziej restrykcyjna niż add() lub addAll() oraz pozwoli Ci przechowywać odpowiedzi inne niż CORS lub inne odpowiedzi, w przypadku których stan kod odpowiedzi nie należy do zakresu 200. Spowoduje to zastąpienie poprzednich odpowiedzi na to samo żądanie.

Tworzenie obiektów żądań

Utwórz obiekt Request, korzystając z adresu URL przechowywanej rzeczy:

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

Praca z obiektami odpowiedzi

Konstruktor obiektów Response akceptuje wiele typów danych, w tym: Blob, ArrayBuffer, FormData obiektów i ciągi.

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

Aby ustawić typ MIME Response, ustaw odpowiedni nagłówek.

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

Jeśli pobrany plik Response został pobrany i chcesz uzyskać dostęp do jego treści, kilka metod pomocniczych. Każda zwraca wartość Promise, która kończy się ma wartość innego typu.

Metoda Opis
arrayBuffer Zwraca ArrayBuffer zawierający treść zserializowany do B.
blob Zwraca Blob. Jeśli Response został utworzony z Blob, to nowy Blob ma taki sam typu. W przeciwnym razie Content-Type Używana jest wartość Response.
text Interpretuje bajty treści jako ciąg zakodowany w formacie UTF-8.
json Interpretuje bajty treści jako ciąg zakodowany w formacie UTF-8, a następnie próbuje do przeanalizowania do formatu JSON. Zwraca wynikowy obiekt lub zwraca TypeError, jeśli ciągu nie można przeanalizować jako JSON.
formData Interpretuje bajty treści jako formularz HTML zakodowany jako multipart/form-data lub application/x-www-form-urlencoded Zwraca FormData lub wysyła TypeError, jeśli nie można przeanalizować danych.
body Zwraca obiekt ReadableStream. dotyczące danych ciała.

Przykład

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]

Pobieram z pamięci podręcznej

Aby znaleźć element w pamięci podręcznej, możesz użyć metody match.

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

Jeśli request jest ciągiem, przeglądarka przekształca go w Request, wywołując new Request(request) Funkcja zwraca Promise, który zwraca Response, jeśli znaleziono pasujący wpis, lub undefined w innym przypadku.

Aby określić, czy 2 elementy Requests pasują, przeglądarka używa więcej niż tylko adresu URL. Dwa żądania są uznawane za różne, jeśli zawierają różne ciągi zapytań, Nagłówki Vary lub metody HTTP (GET, POST, PUT itp.).

Możesz zignorować niektóre lub wszystkie z tych rzeczy, przekazując obiekt options jako jako drugiego parametru.

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

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

Jeśli pasuje więcej niż jedno żądanie w pamięci podręcznej, to żądanie, które zostało utworzone jako pierwsze, . Jeśli chcesz pobrać wszystkie pasujące odpowiedzi, możesz użyć 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.`);

Możesz też przeszukać wszystkie pamięci podręczne jednocześnie, używając skrótu caches.match() zamiast wywoływania cache.match() dla każdej pamięci podręcznej.

Szukam

Interfejs Cache API nie umożliwia wyszukiwania żądań ani odpowiedzi oprócz wpisów zgodnych z obiektem Response. Możesz jednak: użyj własnego wyszukiwania za pomocą filtrów lub przez utworzenie indeksu.

Filtrowanie

Jednym ze sposobów na wdrożenie własnego wyszukiwania jest powtarzanie wszystkich wpisów i możesz filtrować do tych, które są Ci potrzebne. Załóżmy, że chcesz wyszukać wszystkie elementy, których adresy URL kończą się ciągiem .png.

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;
}

Dzięki temu możesz użyć dowolnej właściwości obiektów Request i Response do odfiltrować wpisy. Pamiętaj, że to trwa długo, gdy przeszukujesz duże grupy i skalowalnych danych.

Tworzenie indeksu

Innym sposobem implementacji własnego wyszukiwania jest utrzymywanie osobnego indeksu Wpisy, które można wyszukiwać i przechowywać indeks w IndexedDB. Jest to taki rodzaj dla której została zaprojektowana IndexedDB, działa znacznie lepiej bardzo dużą liczbę wpisów.

Jeśli przechowujesz adres URL obiektu Request obok właściwości dostępnych do przeszukiwania to po przeprowadzeniu wyszukiwania możesz łatwo pobrać prawidłowy wpis w pamięci podręcznej.

Usuwanie elementu

Aby usunąć element z pamięci podręcznej:

cache.delete(request);

Gdzie żądanie może być ciągiem znaków Request lub URL-a. Ta metoda pobiera również ten sam obiekt opcji co obiekt cache.match, który umożliwia usunięcie wielu Pary Request/Response dla tego samego adresu URL.

cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});

Usuwanie pamięci podręcznej

Aby usunąć pamięć podręczną, wywołaj caches.delete(name). Ta funkcja zwraca błąd Promise, który zamienia się na true, jeśli pamięć podręczna istniała i została usunięta, lub W innym przypadku false.

Dziękujemy

Dziękujemy firmie Mat Scales, która napisała oryginalną wersję tego artykułu, pojawiła się po raz pierwszy w WebFundamentals.