CacheStorage
Expérimental: Cette fonction est expérimentale
Puisque cette fonction est toujours en développement dans certains navigateurs, veuillez consulter le tableau de compatibilité pour les préfixes à utiliser selon les navigateurs.
Il convient de noter qu'une fonctionnalité expérimentale peut voir sa syntaxe ou son comportement modifié dans le futur en fonction des évolutions de la spécification.
L'interface CacheStorage
représente le stockage des objets Cache
.
L'interface :
-
Fournit un répertoire principal de tous les caches nommés qui peut être accessible par un
ServiceWorker
ou un autre type de travailleur ou portée dewindow
(vous n'êtes pas limité à l'utiliser uniquement avec des Service Workers, même si la spécification des service workers le définit).Note : Chrome et Safari n'exposent que "CacheStorage" au contexte fenêtré sur HTTPS.
window.caches
sera indéfinie, à moins qu'un certificat SSL ne soit configuré. -
Maintient une correspondance entre les noms des chaînes de caractères et les objets
Cache
correspondants.
Utilisez CacheStorage.open()
pour obtenir une instance Cache
.
Utilisez CacheStorage.match()
pour vérifier si une Requête
donnée est une clé dans l'un des objets Cache
que l'objet CacheStorage
surveille.
Vous pouvez accéder à CacheStorage
via la propriété globale caches
.
Note : CacheStorage échouera systématiquement avec une SecurityError
sur les domaines non certifiés (i.e. ceux qui n'utilisent pas HTTPS, bien que cette définition risque de devenir plus complexe dans le future). Pendant vos tests vous pouvez contourner ce comportement en cochant l'option "Enable Service Workers over HTTP (when toolbox is open)" dans les options Firefox Devtools / le menu gear.
Note : CacheStorage.match()
est une méthode de convenance. Il est possible d'implémenter une fonctionnalité équivalente pour matcher une entrée de cache en appelant CacheStorage.open()
, puis en retournant CacheStorage.keys()
, et en matchant les entrées voulues avec CacheStorage.match()
.
Méthodes
CacheStorage.match()
Expérimental-
Cherche si une
Request
donnée est la clé de n'importe lequel des objetsCache
maintenus par leCacheStorage
, et retourne unePromesse
résolue en cet objetCache
. CacheStorage.has()
Expérimental-
Retourne une
Promesse
qui est résolue entrue
si un objetCache
qui correspond aucacheName
existe. CacheStorage.open()
Expérimental-
Retourne une
Promesse
qui est résolue en l'objetCache
qui correspond aucacheName
(si il n'existe pas, un nouveau cache est créé). CacheStorage.delete()
Expérimental-
Trouve l'objet
Cache
correspondant aucacheName
, et si il est trouvé, supprime l'objetCache
et retourne unePromesse
résolue àtrue
. Si aucun objetCache
n'est trouvé, laPromesse
est résolue àfalse
. CacheStorage.keys()
Expérimental-
Retourne une
Promesse
qui est résolue en un tableau qui contient toutes les chaînes correspondantes aux objetsCache
maintenus par leCacheStorage
. Cette méthode peut s'utiliser pour itérer sur une liste de tous les objetsCache
.
Exemples
Cet extrait de code est tiré de l'exemple MDN sw-test (lancer sw-test dans votre navigateur). Ce service worker script attends le déclenchement d'un InstallEvent
, puis lance waitUntil
pour gérer la phase d'installation de l'app. Cela consiste à appeler CacheStorage.open
pour créer un nouveau cache, puis Cache.addAll
pour y ajouter une série d'assets.
Dans le second bloc de code, on attends le déclenchement d'un FetchEvent
. On construit ensuite une réponse spéciale comme suit :
- Vérifier si il y a un match pour la requête dans le CacheStorage. Le cas échéant, servir ça.
- Sinon, récupérer la requête sur le réseau, puis ouvrir le cache du premier bloc et y ajouter un clone de la requête grâce à
Cache.put
(cache.put(event.request, response.clone())
.) - En cas d'échec (e.g. car le réseau est inaccessible), retourner une réponse par défaut.
Enfin, on retourne cette réponse en utilisant FetchEvent.respondWith
.
this.addEventListener("install", function (event) {
event.waitUntil(
caches.open("v1").then(function (cache) {
return cache.addAll([
"/sw-test/",
"/sw-test/index.html",
"/sw-test/style.css",
"/sw-test/app.js",
"/sw-test/image-list.js",
"/sw-test/star-wars-logo.jpg",
"/sw-test/gallery/",
"/sw-test/gallery/bountyHunters.jpg",
"/sw-test/gallery/myLittleVader.jpg",
"/sw-test/gallery/snowTroopers.jpg",
]);
}),
);
});
self.addEventListener("fetch", function (event) {
event.respondWith(
caches.match(event.request).then(function (response) {
// caches.match() fonctionne toujours
// mais en cas de succès, la réponse aura une valeur
if (response !== undefined) {
return response;
} else {
return fetch(event.request)
.then(function (response) {
// la réponse ne peut être utilisée qu'une seule fois
// nous devons sauvegarder le clone pour mettre
// une copie en cache et servir le second
let responseClone = response.clone();
caches.open("v1").then(function (cache) {
cache.put(event.request, responseClone);
});
return response;
})
.catch(function () {
return caches.match("/sw-test/gallery/myLittleVader.jpg");
});
}
}),
);
});
Cet extrait montre comment l'API peut être utilisée en dehors du contexte d'un Service Worker, et utilise l'opérateur "await" pour un code beaucoup plus lisible.
// Essayer d'obtenir des données du cache, mais se rabattre sur la récupération en direct.
async function getData() {
const cacheVersion = 1;
const cacheName = `myapp-${cacheVersion}`;
const url = "https://jsonplaceholder.typicode.com/todos/1";
let cachedData = await getCachedData(cacheName, url);
if (cachedData) {
console.log("Récupération des données mises en cache");
return cachedData;
}
console.log("Obtenir de nouvelles données");
const cacheStorage = await caches.open(cacheName);
await cacheStorage.add(url);
cachedData = await getCachedData(cacheName, url);
await deleteOldCaches(cacheName);
return cachedData;
}
// Obtenir des données du cache.
async function getCachedData(cacheName, url) {
const cacheStorage = await caches.open(cacheName);
const cachedResponse = await cacheStorage.match(url);
if (!cachedResponse || !cachedResponse.ok) {
return false;
}
return await cachedResponse.json();
}
// Delete any old caches to respect user's disk space.
async function deleteOldCaches(currentCache) {
const keys = await caches.keys();
for (const key of keys) {
const isOurCache = "myapp-" === key.substr(0, 6);
if (currentCache === key || !isOurCache) {
continue;
}
caches.delete(key);
}
}
try {
const data = await getData();
console.log({ data });
} catch (error) {
console.error({ error });
}
Spécifications
Specification |
---|
Service Workers # cachestorage-interface |
Compatibilité des navigateurs
BCD tables only load in the browser