javascript - mis - que pasa si borro los datos de cache de mi celular
El trabajador de servicios está almacenando archivos en caché, pero el evento de captura nunca se activa (4)
Después de analizar su esencia y su pregunta, creo que su problema es con el alcance.
Según lo que he determinado con los trabajadores del servicio (al menos con archivos estáticos), el trabajador del servicio solo tiene un alcance máximo del directorio en el que se encuentra. Es decir, no puede cargar archivos / solicitudes / respuestas que se extraen. desde una ubicación en o encima de su estructura, solo debajo.
Por ejemplo, /js/service-worker.js solo podrá cargar archivos en / js / {dirName} /.
Por lo tanto, si cambia la ubicación de su trabajador de servicio a la raíz de su proyecto web, el evento fetch debería activarse y sus activos deberían cargarse desde el caché.
Algo así como /service-worker.js, que debería poder acceder al directorio / json, ya que es más profundo que el archivo service-worker.js.
Esto se explica con más detalle aquí, en la sección "Registrar un trabajador de servicio". https://developers.google.com/web/fundamentals/getting-started/primers/service-workers
Acabo de intentar implementar trabajadores de servicio para almacenar en caché algunos archivos JSON y otros activos en un sitio estático (ejecutándose en localhost chrome Versión 47.0.2526.73 (64-bit)). Uso de cache.addAll () He agregado mis archivos a la caché, y cuando abro la pestaña de recursos en chrome, y hago clic en el almacenamiento en caché, todos los archivos están en la lista.
El problema que estoy teniendo es que mi trabajador de servicio aparece como "activado" y "ejecutándose" en chrome: // service-worker-internals, sin embargo, no puedo determinar si el trabajador está realmente interceptando las solicitudes y sirviendo los archivos en caché. He agregado la escucha de eventos e incluso cuando consuelo el registro en la instancia de las herramientas de desarrollo de los trabajadores del servicio, nunca llega al punto de interrupción:
this.addEventListener(''install'', function(event) {
event.waitUntil(
caches.open(''v1'').then(function(cache) {
console.log(cache);
return cache.addAll([
''/json/0.json'',
''/json/1.json'',
''/json/3.json'',
''/json/4.json'',
''/json/5.json'',
]);
})
);
});
this.addEventListener(''fetch'', function(event) {
console.log(event);
var response;
event.respondWith(caches.match(event.request).catch(function() {
return fetch(event.request);
}).then(function(r) {
response = r;
caches.open(''v1'').then(function(cache) {
cache.put(event.request, response);
});
return response.clone();
}).catch(function() {
}));
});
Básicamente, estoy ejecutando las cosas exactamente como se describe en la introducción de los trabajadores del servicio HTML5 rocks, pero estoy bastante seguro de que mis activos no se sirven desde el caché. Observé que los activos entregados por un trabajador del servicio se anotan como tales en la pestaña de red de devtools en la columna de tamaño al indicar "de los trabajadores del servicio".
Parece que mi código no es diferente de los ejemplos, pero por alguna razón no llega al evento fetch. Un resumen de mi código: https://gist.github.com/srhise/c2099b347f68b958884d
El código exacto en el artículo de HTML5Rocks es
self.addEventListener(''fetch'', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
// IMPORTANT: Clone the request. A request is a stream and
// can only be consumed once. Since we are consuming this
// once by cache and once by the browser for fetch, we need
// to clone the response
var fetchRequest = event.request.clone();
return fetch(fetchRequest).then(
function(response) {
// Check if we received a valid response
if(!response || response.status !== 200 || response.type !== ''basic'') {
return response;
}
// IMPORTANT: Clone the response. A response is a stream
// and because we want the browser to consume the response
// as well as the cache consuming the response, we need
// to clone it so we have 2 stream.
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
});
Lo más importante que puedo ver es que no está clonando la request
de la búsqueda, debe clonarla porque se lee dos veces, una cuando se usa para acceder a la red (en la fetch
) y otra cuando se usa como la clave para el caché
He luchado con esto durante mucho tiempo, y creo que la documentación relacionada con el asunto es muy deficiente. En mi experiencia, hay una distinción muy importante:
El trabajador del servicio solo puede interceptar eventos de recuperación si está dentro o por encima del alcance de la URL a la que se accede .
Por ejemplo, mi archivo sw.js se encuentra en /static/sw.js
. Al acceder a la raíz de mi sitio en /
y al intentar interceptar eventos de búsqueda en archivos js en /static/js/common.js
, los eventos de búsqueda no fueron interceptados, aunque el alcance de mi trabajador de servicio era /static/
y el archivo js era en /static/js/
.
Una vez que moví mi archivo sw.js al ámbito de nivel superior /sw.js
, todos los eventos de búsqueda fueron interceptados. Esto se debe a que el alcance de la página a la que estaba accediendo con mi navegador /
era el mismo que el alcance de mi archivo sw.js /
.
Por favor, avíseme si esto aclara las cosas para las personas o si soy incorrecto.
Si no ve la marca from service worker
entonces su página aún no está controlada por el trabajador del servicio (puede verificar inspeccionando el navigator.serviceWorker.controller
en la página del cliente). El comportamiento predeterminado de una página es controlarse la próxima vez que la visite después de la activación de SW, por lo que tiene dos opciones:
- Actualizar la página después del registro.
- Utilice los
self.skipWaiting()
yself.clients.claim()
durante la instalación y la activación, respectivamente, para forzar al trabajador del servicio a tomar el control de los clientes lo antes posible.
Mira el Cookbook de Service Worker , incluye una receta de caché JSON .
Una vez que solucione el problema con el control, debe reparar su controlador. Creo que quieres aplicar una política de caché primero . Si no está en el caché, vaya a la red y complete el caché. Para hacer eso:
self.onfetch = function (event) {
var req = event.request;
return event.respondWith(function cacheFirst() {
// Open your cache.
return self.caches.open(''v1'').then(function (cache) {
// Check if the request is in there.
return cache.match(req).then(function (res) {
// If not match, there is no rejection but an undefined response.
if (!res) {
// Go to network.
return fetch(req.clone()).then(function (res) {
// Put in cache and return the network response.
return cache.put(req, res.clone()).then(function () {
return res;
});
});
}
return res;
});
});
});
}