CacheStorage
============

La interfaz **`CacheStorage`** representa el almacenamiento para objetos `Cache` (en-US).

La interfaz:

* Proporciona un directorio maestro de todos los cachés con nombre a los que se puede acceder mediante un `ServiceWorker` (en-US) u otro tipo de trabajador o alcance de `window` (no está limitado a usándolo solo con *service worker*).
* Mantiene una asignación de nombres de cadenas a objetos `Cache` (en-US) correspondientes

Utilice `CacheStorage.open()` para obtener una instancia de `Cache` (en-US).

Usa `CacheStorage.match()` (en-US) para verificar si un `Request` dado es una clave en cualquiera de los `Cache` (en-US) objetos que el objeto `CacheStorage` rastrea.

Puede acceder a `CacheStorage` a través de la propiedad global `caches`.

**Nota:** `CacheStorage` siempre rechaza con un `SecurityError` en orígenes que no son de confianza (es decir, aquellos que no usan HTTPS, aunque esta definición probablemente se volverá más compleja en el futuro). Al probar en Firefox, puede evitar esto marcando la opción **Activar service workers bajo HTTP (cuando la caja de herramientas esté abierta)** en el menú de opciones/engranaje de las Herramientas de desarrollador de Firefox. Además, debido a que `CacheStorage` requiere acceso al sistema de archivos, es posible que no esté disponible en modo privado en Firefox.

**Nota:** `CacheStorage.match()` (en-US) es un método conveniente. Se puede implementar una funcionalidad equivalente para hacer coincidir una entrada de caché devolviendo una matriz de nombres de caché desde `CacheStorage.keys()`, abriendo cada caché con `CacheStorage.open()`, y haciendo coincidir el que quieras con `Cache.match()` (en-US).

**Nota:** Esta característica está disponible en Web Workers

**Contexto seguro:** Esta función está disponible solo en contextos seguros (en-US) (HTTPS), en algunos o todos los navegadores que lo soportan.

Métodos de instancia
--------------------

`CacheStorage.match()` (en-US)

Comprueba si un objeto `Request` dado es una clave en cualquiera de los objetos `Cache` (en-US) que rastrea el objeto `CacheStorage` y devuelve un `Promise` que se resuelve en esa coincidencia.

`CacheStorage.has()` (en-US)

Devuelve un `Promise` que se resuelve en `true` si existe un objeto `Cache` (en-US) que coincide con `cacheName`.

`CacheStorage.open()`

Devuelve un `Promise` que se resuelve en el objeto `Cache` (en-US) que coincide con `cacheName` (se crea un nuevo caché si aún no existe).

`CacheStorage.delete()` (en-US)

Encuentra el objeto `Cache` (en-US) que coincide con `cacheName` y, si lo encuentra, elimina el objeto `Cache` (en-US) y devuelve un `Promise` que se resuelve en `true`. Si no se encuentra ningún objeto `Cache` (en-US), se resuelve como `false`.

`CacheStorage.keys()`

Devuelve un `Promise` que se resolverá con una matriz que contiene cadenas correspondientes a todos los objetos `Cache` (en-US) nombrados rastreados por `CacheStorage`. Utilice este método para iterar sobre una lista de todos los objetos `Cache` (en-US).

Ejemplos
--------

 Este fragmento de código de MDN ejemplo simple de *service worker* (vea simple *service worker* ejecutándose en vivo.)
 Este código de *service worker* espera que se active un `InstallEvent` (en-US), luego ejecuta `waitUntil` (en-US) para manejar el proceso de instalación de la aplicación. Esto consiste en llamar a `CacheStorage.open` para crear un nuevo caché, luego usar `Cache.addAll` (en-US) para agregarle una serie de activos.

En el segundo bloque de código, esperamos que se active un `FetchEvent`. Construimos una respuesta personalizada así:

1. Compruebe si se encuentra una coincidencia para la solicitud en CacheStorage. Si es así, entrega eso.
2. De lo contrario, obtenga la solicitud de la red, luego abra también el caché creado en el primer bloque y agregue un clon de la solicitud usando `Cache.put` (en-US) (`cache.put(event.request, response.clone())`).
3. Si esto falla (por ejemplo, porque la red no funciona), devuelva una respuesta alternativa.

Finalmente, devuelva lo que sea que la respuesta personalizada terminó siendo igual a, usando `FetchEvent.respondWith` (en-US).


```js
self.addEventListener("install", (event) => {
  event.waitUntil(
    caches
      .open("v1")
      .then((cache) =>
        cache.addAll([
          "/",
          "/index.html",
          "/style.css",
          "/app.js",
          "/image-list.js",
          "/star-wars-logo.jpg",
          "/gallery/bountyHunters.jpg",
          "/gallery/myLittleVader.jpg",
          "/gallery/snowTroopers.jpg",
        ]),
      ),
  );
});

self.addEventListener("fetch", (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      // caches.match() siempre se resuelve,
      // pero en caso de éxito, la respuesta tendrá valor
      if (response !== undefined) {
        return response;
      } else {
        return fetch(event.request)
          .then((response) => {
            // la respuesta puede usarse solo una vez
            // que necesitamos guardar el clon para poner
            // una copia en caché y entregar la segunda
            let responseClone = response.clone();

            caches.open("v1").then((cache) => {
              cache.put(event.request, responseClone);
            });
            return response;
          })
          .catch(() => caches.match("/gallery/myLittleVader.jpg"));
      }
    }),
  );
});
```


Este fragmento muestra cómo se puede usar la API fuera del contexto de un *service worker* y usa el operador `await` para obtener un código mucho más legible.


```js
// Intente obtener datos del caché, pero recurra a buscarlos en vivo.
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("Datos almacenados en caché recuperados");
    return cachedData;
  }

  console.log("Obtener datos nuevos");

  const cacheStorage = await caches.open(cacheName);
  await cacheStorage.add(url);
  cachedData = await getCachedData(cacheName, url);
  await deleteOldCaches(cacheName);

  return cachedData;
}

// Obtener datos del caché.
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();
}

// Elimine los cachés antiguos para respetar
// el espacio en disco del usuario.
async function deleteOldCaches(currentCache) {
  const keys = await caches.keys();

  for (const key of keys) {
    const isOurCache = key.startsWith("myapp-");
    if (currentCache === key || !isOurCache) {
      continue;
    }
    caches.delete(key);
  }
}

try {
  const data = await getData();
  console.log({ data });
} catch (error) {
  console.error({ error });
}
```

Especificaciones
----------------

| Specification |
| --- |
| Service Workers # cachestorage-interface |

Compatibilidad con navegadores
------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Véase también
-------------

* Uso de *Service Workers*
* `Cache` (en-US)
* `caches`
* Navegación privada / Modos de incógnito