The service worker's fetch
event handler isn't being called the first time you load the page because the service worker hasn't yet "claimed" the page, meaning it's not under the service worker's control. By default, the first time you visit a site that registers a service worker, the service worker's install
(and potentially activate
) event handlers will run, but fetch
won't get triggered until the service worker takes control. That happens the next time you navigate to a page under the service worker's scope, or if you reload the current page.
You can override this default behavior and have the service worker take control during the initial navigation by calling self.clients.claim()
inside your activate
event handler.
I also want to point out that the fetch
event handler in your sample has some issues—there's no reason to call caches.match(request)
if you're always planning on returning a new Response
object. More importantly, you need to do some sort of check of the event.request.url
value and only return the new Response
if it matches one of your "special" URLs, which in your case is a
and b
. The way things are implemented now, your fetch
handler will return the dummy Response
unconditionally, even if it's a subsequent request for your main page (index.html
). That's presumably not what you want.
I put a gist together that modifies your service worker code to accomplish what I believe you're attempting. You can try out a live version thanks to RawGit. For posterity, here's the modified service worker code:
self.addEventListener('install', event => {
// Bypass the waiting lifecycle stage,
// just in case there's an older version of this SW registration.
event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', event => {
// Take control of all pages under this SW's scope immediately,
// instead of waiting for reload/navigation.
event.waitUntil(self.clients.claim());
});
self.addEventListener('fetch', event => {
// In a real app, you'd use a more sophisticated URL check.
if (event.request.url.match(/a|b$/)) {
event.respondWith(new Response('here is your onfetch response'));
}
});