I've written a service worker with help from a tutorial:
var CACHE = 'cache-and-update';
self.addEventListener('install', function (evt) {
console.log('The service worker is being installed.');
evt.waitUntil(precache());
});
self.addEventListener('fetch', function (evt) {
evt.respondWith(fromCache(evt.request));
evt.waitUntil(update(evt.request));
});
function precache() {
return caches.open(CACHE).then(function (cache) {
return cache.addAll([
// Nothing.
]);
});
}
function fromCache(request) {
return caches.open(CACHE).then(function (cache) {
return cache.match(request).then(function (matching) {
return matching || Promise.reject('no-match');
});
});
}
function update(request) {
return caches.open(CACHE).then(function (cache) {
return fetch(request).then(function (response) {
return cache.put(request, response);
});
});
}
It always serves from the cache first, then fetches all files, and updates on page reload.
The service worker is registered like this in every HTML file on my server:
<script>
navigator.serviceWorker.register('https://www.example.com/sw.js', {
scope: '../'
});
</script>
Now the problem is, when I go to a page that isn't cached yet, it first shows me the default Chrome ERR_FAILED error (and the 'no-match' promise rejection).
The sw then fetches it anyway, while showing the error page to the client, and on a reload it works again (because it's served from the cache).
Why is this happening and how can I make the service worker load the page from the server when there's no cached version available?