I have a simple service worker, that adds two resources (index.html, app.js) to the cache (on install), deletes old caches (on activate) and serves the resources from cache if present, else from the network (on fetch). To get the new service worker registered and to delete old caches I increase the version number in CACHE_NAME with each version of new resources:
var CACHE_NAME = 'test-cache-v4';
var urlsToCache = ['./','./app.js'];
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function (cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
return self.skipWaiting();
});
self.addEventListener('activate', function(event) {
event.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (key !== CACHE_NAME) {
return caches.delete(key);
}
}));
})
);
});
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.open(CACHE_NAME).then(function(cache){
return cache.match(event.request)
.then(function(response) {
if (response) {
console.log('SERVED FROM CACHE');
return response;
}
return fetch(event.request).then(function(response){
console.log('Response from network is:', response);
return response;
});
}
)
})
);
});
On my localhost the service worker works perfectly fine.
But on the server the response/promise returned by
return cache.match(event.request)
is always undefined. As a result the resources are never served from cache but always from network.
This happens even though in Chrome's dev tools "Application" tab I can see that registration of the new service worker works fine and "Cache Storage" gets filled with my new cache resources (request URLs to index.html and app.js). I also think that I have handled the web server config tweaks correctly with Cache-Control no-cache.
If I change
return cache.match(event.request)
to
return cache.match(event.request.url)
the service worker also works on the server.
However, I would like to understand why the syntax that seems right to me and is used in all the examples I can find does not work on the server.
One difference is that I access localhost directly and the server over https.
EDIT: Another difference is that resources from the server are compressed (Header => content-encoding:gzip).
Could it be linked to one of these differences?
Any ideas are greatly appreciated!
1. no-cache
Try to cancel cache mechanism in your server, i found these code in my remote Apache server (served over HTTPS):
My localhost is not served over HTTPS, and the example How to Setup a Basic Service Worker works fine on it.
2. Match Method
Cache.match() - Web APIs | MDN shows that parameter should be the Request you are attempting to find in the Cache. But
cache.match(event.request.url)
works as well in localhost and remote Apache Server. Caching has no problem.3. Gzip
After test in localhost(no gzip) and remote Apache server(gzip), both caching files without any error. So gzip is not one of the reason.