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?