Reputation: 83358
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));
}
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.
Upvotes: 14
Views: 8706
Reputation: 997
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: /
Upvotes: 9
Reputation: 166
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.
Upvotes: 3
Reputation: 1
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
Upvotes: 2