Service Workers can interfere with the refresh button (by design). On desktop Chrome, you can hold shift and click the refresh button to do a hard reload, ignoring any installed ServiceWorker.
Is there a way to force a reload ignoring the SW in JavaScript?
(I want this so I can give mobile users a button to push if the SW starts misbehaving. Phones don't have a shift key.)
js. A one-character change in the controlling service-worker. js will automatically trigger a PWA update. Hence, if you store the version number in a const in this file and change it, an update of the PWA will be triggered.
A service worker is run in a worker context: it therefore has no DOM access, and runs on a different thread to the main JavaScript that powers your app, so it is non-blocking. It is designed to be fully async; as a consequence, APIs such as synchronous XHR and Web Storage can't be used inside a service worker.
unregister() The unregister() method of the ServiceWorkerRegistration interface unregisters the service worker registration and returns a Promise .
If you unregister
the Service Worker before refreshing, the next page load will load without the Service Worker.
navigator.serviceWorker.getRegistration().then(function(reg) {
if (reg) {
reg.unregister().then(function() { window.location.reload(true); });
} else {
window.location.reload(true);
}
});
Here is an example of what I commented on:
page script:
if('serviceWorker' in navigator){
// Register service worker
navigator.serviceWorker.register('/service-worker.js')
.then(
reg =>
console.log("SW registration succeeded. Scope is "+reg.scope)
,err =>
console.error("SW registration failed with error "+err)
);
}
const send_message_to_sw = (msg) =>
new Promise(
(resolve, reject) => {
// Create a Message Channel
const msg_chan = new MessageChannel();
// Handler for recieving message reply from service worker
msg_chan.port1.onmessage = (event) => {
if(event.data.error){
reject(event.data.error);
}else{
resolve(event.data);
}
};
// Send message to service worker along with port for reply
navigator.serviceWorker.controller.postMessage(
msg
, [msg_chan.port2]
);
}
);
document.body.addEventListener(
"click"
,()=>
send_message_to_sw(
{
action:"delete"
,cache:/^v1$/
,url:/.*bundle.js$/
}
)
.then(
(msg)=>
console.log("deleted:",msg)
)
);
Service worker:
console.log("SW Startup!");
// Install Service Worker
self.addEventListener(
'install'
,(event)=>
console.log('installed!')
);
// Service Worker Active
self.addEventListener(
'activate'
,(event)=>
console.log('activated!')
);
self.addEventListener(
'fetch'
,(event) =>
event.respondWith(
caches.match(event.request)
.then((resp) =>
resp
||
fetch(event.request)
.then(
(response) =>
caches.open('v1')
.then(
(cache) => {
cache.put(event.request, response.clone());
return response;
}
)
)
)
)
);
self.addEventListener(
'message'
,(event) =>{
const data = event.data || {};
if(data.action === "delete"){
var p =
caches.keys()
.then(
(keyList) =>
keyList
.filter(
key=>data.cache.test(key)
)
)
;
if(data.url === undefined) {
p = p.then(
(keyList) =>
Promise.all(
keyList
.map((key) =>{
caches.delete(key);
return key;
}
)
)
)
}else {
p = p.then(
(keyList) =>
Promise.all(
keyList
.map((key) =>
caches.open(key)
.then(
(cache)=>
Promise.all([
cache
,cache.keys()
])
)
.then(
([cache,items])=>
Promise.all(
items
.filter(item=>data.url.test(item.url))
.map(
item=>{
cache.delete(item);
return key + ":" + item.url
}
)
)
)
)
)
)
}
return p.then(
(keys)=>
event.ports[0].postMessage(
keys
.reduce(
(acc,item)=>acc.concat(item)
,[]
)
)
);
}
}
);
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