When using workbox (5.1.3) and setting up the service-worker.js like
precacheAndRoute([
{url: '/version.txt', revision: 'v1' },
]);
I can navigate in browser to localhost://version.txt
and see inside chrome console that this content is fetched via caching from workbox.
Message in console shows:
workbox Precaching is responding to: /version.txt
But when trying to fetch the resource inside my javascript app via:
window
.fetch('/version.txt')
.then((response) => {
if (response.status >= 200 && response.status < 300) {
return response.text();
} else {
throw Error('no version');
}
})
.then((data) => {
console.log('content: ' + data);
})
.catch((error) => {
console.log(error);
});
}
the fetch command will try to read this content directly from network and skipping workbox Precaching. Also when simulating offline, I get an error for fetch instead the cached response.
Getting crazy ;-)
After digging further into this issue - I found the problem (at least on my site)
Full working example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My New Project!</title>
</head>
<body>
<h1>Example Service Worker</h1>
<p>A simple Test</>
<!-- Scripts -->
<script src="index.js"></script>
</body>
</html>
let registration;
var initServiceWorker = () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('./sw.js')
.then((reg) => registration = reg)
.catch((error) => console.log('Registration failed with ' + error));
}
}
var fetchTest = () => {
console.log('VERSION FETCH Test looking for: /version.txt');
window
.fetch('/version.txt', { method: 'GET'})
.then((response) => {
if (response.status >= 200 && response.status < 300) {
return response.text();
} else {
throw Error('no version.txt file');
}
})
.then((data) => {
console.log('AVILABLE VERSION FETCH: ' + String(data).trim());
})
.catch((error) => {
console.log(error);
});
}
var xmlhttpTest = () => {
console.log('VERSION XHR Test looking for: /version.txt');
var xhr = new XMLHttpRequest();
xhr.open("GET", '/version.txt', true);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log('AVILABLE VERSION XHR: ' + xhr.responseText);
}
}
}
// initialize request
xhr.send(null);
}
console.log("JavaScript is amazing!");
initServiceWorker();
setTimeout(() => fetchTest(), 5000);
setTimeout(() => xmlhttpTest(), 10000);
setTimeout(() => { console.log('Registration update ...'); registration.update()}, 20000);
setTimeout(() => fetchTest(), 30000);
setTimeout(() => xmlhttpTest(), 35000);
// Sample service worker
const SW_VERSION = 'a2';
self.addEventListener('install', (event) => {
console.log('SW INSTALL: ' + SW_VERSION);
skipWaiting();
});
self.addEventListener('activate', (event) => {
console.log('SW ACTIVATE: ' + SW_VERSION);
skipWaiting();
});
self.addEventListener("fetch", function(event) {
console.log('WORKER (' + SW_VERSION + '): fetch event in progress ... ' + event.request.url);
if (event.request.method !== 'GET') {
console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
return;
}
});
v1.0.0
You may have a look into your console to see that also while using FETCH or XMLHTTREQUEST the fetch event from service worker will drop a message.
If placing the javascript (/index.js) with fetch and xmlHttprequest in the same place (scope) as service-worker (/sw.js) everything works as expected
BUT
if leaving the javascript in a subfolder like (/js/index.js) THIS WON'T TOUCH THE FETCH LISTENER from service-worker (/sw.js) ANYMORE even if /js should be in scope???
Strange but happy to get that now ;-)