Découvrez comment utiliser l'API Cache pour rendre les données de vos applications disponibles hors connexion.
L'API Cache est un système de stockage et de récupération de requêtes et les réponses correspondantes. Il peut s'agir de requêtes standards et des réponses créées au cours de l'exécution de votre application, être créées uniquement dans le but de stocker des données pour une utilisation ultérieure.
L'API Cache a été créée pour permettre aux service workers de mettre en cache les requêtes réseau afin de fournir des réponses rapides, quel que soit le débit du réseau ou la disponibilité. Cependant, l'API peut également servir de mécanisme de stockage général.
Où ce service est-il disponible ?
L'API Cache est disponible dans tous les navigateurs récents. Il est
exposées via la propriété globale caches
. Vous pouvez ainsi tester la présence
l'API avec une simple détection de caractéristiques:
const cacheAvailable = 'caches' in self;
Navigateurs pris en charge
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
L'API Cache est accessible depuis une fenêtre, un iFrame, un worker ou un service worker.
Que peut-on stocker ?
Les caches ne stockent que les paires de Request
et
des objets Response
, représentant des requêtes et réponses HTTP,
respectivement. Cependant, les requêtes et les réponses peuvent contenir tout type de données
transférables via HTTP.
Quelle quantité peut être stockée ?
En bref, beaucoup, au moins quelques centaines de mégaoctets, et potentiellement des centaines de gigaoctets ou plus. Les implémentations de navigateur varient, mais la quantité disponible est généralement basé sur l'espace de stockage disponible l'appareil.
Créer et ouvrir un cache
Pour ouvrir un cache, utilisez la méthode caches.open(name)
, en transmettant le nom du
cache comme paramètre unique. Si le cache nommé n'existe pas, il est
créé. Cette méthode renvoie un Promise
qui se résout avec l'objet Cache
.
const cache = await caches.open('my-cache');
// do something with cache...
Ajout à un cache
Il existe trois façons d'ajouter un élément à un cache : add
, addAll
et put
.
Les trois méthodes renvoient un Promise
.
cache.add
Tout d'abord, il y a cache.add()
. Elle accepte un seul paramètre : un Request
ou une URL (string
). Il envoie une requête au réseau et stocke la réponse
dans le cache. Si le
ou si le code d'état de la réponse
n'est pas compris dans la plage 200,
alors rien n'est stocké, et Promise
le rejette. Notez que les données multi-origines
les requêtes qui ne sont pas en mode CORS ne peuvent pas être stockées, car elles renvoient un status
0
Ces requêtes ne peuvent être stockées qu'avec 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
Ensuite, il y a cache.addAll()
. Son fonctionnement est semblable à celui de add()
, mais il prend une
Tableau d'objets Request
ou d'URL (string
). Ce fonctionnement est semblable à
en appelant cache.add
pour chaque requête individuelle, sauf que Promise
rejette si une requête unique n'est pas mise en cache.
const urls = ['/weather/today.json', '/weather/tomorrow.json'];
cache.addAll(urls);
Dans chacun de ces cas, une nouvelle entrée remplace toute entrée correspondante existante. Les règles de correspondance sont les mêmes que celles décrites dans la section la récupération.
cache.put
Enfin, cache.put()
, qui vous permet de stocker une réponse
à partir du réseau, ou créer et stocker vos propres Response
. Il faut deux
paramètres. Le premier peut être un objet Request
ou une URL (string
).
Le second doit être un Response
, issu du réseau ou généré par votre
du code source.
// 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');
La méthode put()
est plus permissive que add()
ou addAll()
.
vous permet de stocker des réponses autres que CORS, ou d'autres réponses dont l'état
code de réponse n'est pas compris dans la plage 200. Elle écrasera les éventuelles
pour la même demande.
Créer des objets Request
Créez l'objet Request
à l'aide d'une URL pour l'élément stocké:
const request = new Request('/my-data-store/item-id');
Utiliser des objets Response
Le constructeur d'objet Response
accepte de nombreux types de données, y compris
Blob
, ArrayBuffer
, objets FormData
et chaînes.
const imageBlob = new Blob([data], {type: 'image/jpeg'});
const imageResponse = new Response(imageBlob);
const stringResponse = new Response('Hello world');
Vous pouvez définir le type MIME d'un élément Response
en définissant l'en-tête approprié.
const options = {
headers: {
'Content-Type': 'application/json'
}
}
const jsonResponse = new Response('{}', options);
Si vous avez récupéré un Response
et que vous souhaitez accéder à son corps, il existe
plusieurs méthodes d'assistance que vous pouvez utiliser. Chacune d'elles renvoie un Promise
qui résout
avec une valeur d'un type différent.
Méthode | Description |
---|---|
arrayBuffer |
Renvoie un ArrayBuffer contenant le corps, sérialisé à
octets.
|
blob |
Renvoie un objet Blob . Si Response a été créé
avec un Blob , ce nouveau Blob aura le même
de mots clés. Sinon, le Content-Type de
Response est utilisé.
|
text |
Interprète les octets du corps en tant que chaîne encodée au format UTF-8. |
json |
Interprète les octets du corps comme une chaîne encodée en UTF-8, puis essaie
pour l'analyser au format JSON. Renvoie l'objet obtenu ou génère une
TypeError si la chaîne ne peut pas être analysée au format JSON.
|
formData |
Interprète les octets du corps de texte sous forme HTML, encodé sous forme de code
multipart/form-data ou
application/x-www-form-urlencoded Renvoie une
FormData
ou génère une erreur TypeError si les données ne peuvent pas être analysées.
|
body |
Renvoie un ReadableStream pour les données corporelles. |
Exemple :
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]
Récupérer depuis un cache
Pour rechercher un élément dans un cache, vous pouvez utiliser la méthode match
.
const response = await cache.match(request);
console.log(request, response);
Si request
est une chaîne, le navigateur le convertit en Request
en appelant
new Request(request)
La fonction renvoie un Promise
qui résout
Response
si une entrée correspondante est trouvée, ou undefined
dans le cas contraire.
Pour déterminer si deux Requests
correspondent, le navigateur ne se limite pas à l'URL. Deux
sont considérées comme différentes si elles ont des chaînes de requête différentes,
En-têtes Vary
ou méthodes HTTP (GET
, POST
, PUT
, etc.).
Vous pouvez ignorer tout ou partie de ces éléments en transmettant un objet options en tant que deuxième paramètre.
const options = {
ignoreSearch: true,
ignoreMethod: true,
ignoreVary: true
};
const response = await cache.match(request, options);
// do something with the response
Si plusieurs requêtes mises en cache correspondent, celle qui a été créée en premier est
renvoyé. Si vous souhaitez récupérer toutes les réponses correspondantes, vous pouvez utiliser
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.`);
Comme raccourci, vous pouvez effectuer une recherche dans tous les caches à la fois en utilisant caches.match()
au lieu d'appeler cache.match()
pour chaque cache.
Recherche en cours
L'API Cache ne permet pas de rechercher des requêtes ou des réponses
à l'exception des entrées correspondantes avec un objet Response
. Cependant, vous pouvez
implémenter votre propre recherche en filtrant ou en créant un index.
Filtrage
Une façon d'implémenter votre propre recherche consiste à itérer sur toutes les entrées et
et filtrez les données
pour n'afficher que ceux qui vous intéressent. Disons que vous voulez trouver toutes
articles dont l'URL se termine par .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;
}
De cette façon, vous pouvez utiliser n'importe quelle propriété des objets Request
et Response
pour :
filtrer les entrées. Notez que cela peut prendre du temps si vous effectuez une recherche sur de grands ensembles
données.
Créer un index
L'autre façon d'implémenter votre propre recherche consiste à gérer un index distinct de les entrées pouvant faire l'objet d'une recherche et stocker l'index dans IndexedDB. Puisqu’il s’agit du genre de pour laquelle IndexedDB a été conçu offre de bien meilleures performances, un grand nombre d'entrées.
Si vous stockez l'URL de Request
avec les propriétés incluses dans l'index de recherche
vous pouvez facilement récupérer l’entrée de cache
correcte après avoir effectué la recherche.
Supprimer un élément
Pour supprimer un élément d'un cache:
cache.delete(request);
Où la requête peut être une chaîne Request
ou une chaîne d'URL. Cette méthode utilise également
le même objet d'options que cache.match
, ce qui vous permet de supprimer plusieurs
Request
/Response
pour la même URL.
cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});
Supprimer un cache
Pour supprimer un cache, appelez caches.delete(name)
. Cette fonction renvoie une
Promise
qui résout true
si le cache existait et a été supprimé ; ou
false
dans le cas contraire.
Merci
Grâce à Mat Scales, qui a rédigé la version originale de cet article, est apparu pour la première fois sur WebFundamentals.