Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service Worker's fetch event never fires

The question title says it all.

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/react-redux/sw.js').then(() => {
        console.log('registered');
    }, err => console.log(err));
}

EDIT

It looks like the root of the problem is the path

navigator.serviceWorker.register('/react-redux/sw.js')

if I move the sw code, so that I have

navigator.serviceWorker.register('swRoot.js').then(() => {

then everything works properly. I tried just about everything I can think of above, from dropping the leading slash in /react-redux, to adding a {scope: of './', '/', '/react-redux', and none worked (with some causing errors).

Does anyone know what config magic is needed to be able to load a service worker from somewhere other than the root of your domain?


and then my entire sw.js

self.addEventListener('install', function(event) {
    console.log('hello');
    try {
        console.log('typeof System in install', typeof System);
    } catch(e){}

    console.log('caching');
    event.waitUntil(
        caches.open('v1').then(function(cache) {
            console.log('caching - getting');
            return cache.addAll([
                '/react-redux/a.js'
            ]);
        }).catch(function(error){ console.log('error', error) })
    );
});

console.log('ADDING FETCH')
self.addEventListener('fetch', function(event) {
    console.log('fetching ->', event.request);
    event.respondWith(
        caches.match(event.request)
                .then(function(response) {
                    // Cache hit - return response
                    if (response) {
                        return response;
                    }
                    return fetch(event.request);
                })
    );
});

I never ever get the console.log('fetching ->', event.request); message. I even added this silliness to try to force the issue.

setTimeout(() => fetch('/react-redux/foo.css').then(r => console.log(r)), 1000);
setInterval(() => fetch('/react-redux/foo.css').then(r => console.log(r)), 5000);

I see the fetch events running, but the service worker never says it's hitting those event handlers.

Moreover, I do get notified that the SW is registered, and when I update sw.js, close and re-open, I see all the logging statements indicating that things are installing correctly.

like image 430
Adam Rackis Avatar asked Dec 08 '16 19:12

Adam Rackis


People also ask

What is a fetch event?

This is the event type for fetch events dispatched on the service worker global scope. It contains information about the fetch, including the request and how the receiver will treat the response. It provides the event. respondWith() method, which allows us to provide a response to this fetch.

What is service worker cache?

To do this, we use Service Worker's storage API — cache — a global object on the service worker that allows us to store assets delivered by responses, and keyed by their requests. This API works in a similar way to the browser's standard cache, but it is specific to your domain.

What is service worker scope?

The scope is defined during the registration of the Service Worker - the scope specifies from which directory the requests of the Progressive Web App are controlled. The scope of the Services Worker is defined during registration and can only be below the respective path.


2 Answers

You're on the right track, it seems to be a scoping issue.

To change the scope of a service worker, it must be done when registering, like this:

navigator.serviceWorker.register('scripts/sw.js', { scope: '/' })

Then the server must return the following header in the response to acknowledge this scope change.

Service-Worker-Allowed: /

See this answer

like image 155
Derek Avatar answered Oct 24 '22 10:10

Derek


Attach fetch event listener within install event handler

self.addEventListener('install', function(event) {
  console.log("install");
  try {
    console.log('typeof System in install', typeof System);
  } catch (e) {}

  console.log('caching');
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      console.log('caching - getting');
      return cache.addAll([
        'a.js'
      ]);
    }).catch(function(error) {
      console.log('error', error)
    })
  );

  self.addEventListener('fetch', function(event) {
    console.log('fetching ->', event.request);
    event.respondWith(
      caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
    );
  });
});

plnkr https://plnkr.co/edit/WuJCZSD0V4idG1Ra7VMb?p=preview

like image 3
guest271314 Avatar answered Oct 24 '22 10:10

guest271314