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