Let's get into details :
The page which is served (through the http://localhost:8080/place/test url) has some client side JS, in which I register a Service Worker :
client.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register(rootPath+'/js/service-worker.js')
.then(function() { console.log('Service Worker Registered'); });
}
service-worker.js (based on the Google PWA tutorial)
var cacheName = 'myCacheVersion';
var filesToCache = [
'../',
'../place/test',
'../js/client.js',
'../js/service-worker.js',
"../css/style.css"
];
self.addEventListener('install', function(e) {
console.log('[ServiceWorker] Install');
e.waitUntil(
caches.open(cacheName).then(function(cache) {
console.log('[ServiceWorker] Caching app shell');
return cache.addAll(filesToCache);
})
);
});
self.addEventListener('activate', function(e) {
console.log('[ServiceWorker] Activate');
e.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (key !== cacheName) {
console.log('[ServiceWorker] Removing old cache', key);
return caches.delete(key);
}
}));
})
);
return self.clients.claim();
});
self.addEventListener('fetch', function(e) {
console.log('[ServiceWorker] Fetch', e.request.url);
e.respondWith(
caches.match(e.request).then(function(response) {
return response || fetch(e.request);
})
);
});
In the Dev Tools Console, everything seems fine :
But when I check the Offline mode checkbox and refresh my page url : http://localhost:8080/place/test , I only get the Google Chrome Offline Web Page.
=> What am I missing there ? (does it have to do with nodeJs ? with the localhost environment ? with my implementation ?)
I've been struggling with this one for a little while now...
I have checked in the "Application" tab and my service worker shows up as activated and is running.
Note : If found a similar question here, but no satisfying answer over there : Service worker not run in offline mode using nodejs server
Fundamentally this is the same problem as answered here: Service worker is caching files but fetch event is never fired
If you look in your console, you'll see that while the install, activate, caching, and registration all happen, the "fetch" won't. This is because you located the service worker under js
, so for security reasons Chrome (etc) won't use it for any URLs except those in the same directory or below.
If you place your client.js
and service-worker.js
at the same level rather than in a js
subdirectory, it will all start working. That will necessitate updating the contents of the files, which I will show below for reference.
One tiny caveat: I foolishly used IIS on a Windows box to work on this, and between that and Chrome they clung like grim death to the cached HTML files with outdated JS-file locations. I had to copy them into a subdirectory, making fresh URLs, to test the solution.
index.html
:
<head>
<script src="client.js"></script>
</head>
<body>
<a href="cachetest.html">link to ct</a>
</body>
cachetest.html
:
<head>
<script src="client.js"></script>
</head>
<body>cachetest</body>
client.js
:
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('service-worker.js')
.then(function() { console.log('Service Worker Registered'); });
}
serviceworker.js
:
var cacheName = 'myCacheVersion';
var filesToCache = [
'',
'cachetest.html',
'client.js',
'service-worker.js',
// "css/style.css"
];
self.addEventListener('install', function(e) {
console.log('[ServiceWorker] Install');
e.waitUntil(
caches.open(cacheName).then(function(cache) {
console.log('[ServiceWorker] Caching app shell');
return cache.addAll(filesToCache);
})
);
});
self.addEventListener('activate', function(e) {
console.log('[ServiceWorker] Activate');
e.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (key !== cacheName) {
console.log('[ServiceWorker] Removing old cache', key);
return caches.delete(key);
}
}));
})
);
return self.clients.claim();
});
self.addEventListener('fetch', function(e) {
console.log('[ServiceWorker] Fetch', e.request.url);
e.respondWith(
caches.match(e.request).then(function(response) {
return response || fetch(e.request);
})
);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With