最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Service Worker's fetch event never fires - Stack Overflow

programmeradmin1浏览0评论

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.

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.

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Dec 8, 2016 at 19:56 Adam RackisAdam Rackis 83.4k57 gold badges278 silver badges400 bronze badges 5
  • Can you create a plnkr plnkr.co to demonstrate? – guest271314 Commented Dec 8, 2016 at 20:09
  • @guest271314 - It'd likely be non-trivial to do so. I'm hoping a SW expert can look at the code and see what the problem may be. – Adam Rackis Commented Dec 8, 2016 at 20:30
  • plnkr allows creation of files and ServiceWorker. javascript at Question should be able to be reproduced – guest271314 Commented Dec 8, 2016 at 20:33
  • 1 The difficult part would be getting resources in place to request from within plnkr, to test whether they were working with the SW. – Adam Rackis Commented Dec 8, 2016 at 20:35
  • Not sure what you mean? You can create new files at plnkr by clicking New file, for example, foo.css, then call fetch() with file name as parameter within script.js – guest271314 Commented Dec 8, 2016 at 20:38
Add a comment  | 

3 Answers 3

Reset to default 9

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

Getting fetch interception working seems to require that the registered service worker be at or above the level of the tree with the HTML file registering the worker. Below fails.

In Chrome, be sure to look at "Service Worker" under "Application". Even registering below results in a Service Worker which is activated and running, but when the location is at or above the HTML page, you also get an entry listed under "Clients". The presence of this seems to correspond exactly to when the fetch will be intercepted.

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

发布评论

评论列表(0)

  1. 暂无评论