Reputation: 7480
I want to create a website that can work even when it's server is offline — I found that that's what ServiceWorkers are for.
When I reload the page with service worker and no connectivity, it works just fine. However, shift+reload (e.g. bypassing cache) disarms service worker and I get "could not connect to server" error.
My question is — can I somehow prevent shift+reload (shift+f5, ctrl+f5 etc) from ruining service worker, or, at least, make it recover afterwards without restoring connectivity?
Upvotes: 6
Views: 3931
Reputation: 15519
I was able to solve this by detecting the ctrl+shift+r
and reloading:
const wb = new Workbox(swUrl)
const wbReg = await wb.register({ immediate: true })
// workaround for ctrl + shift + r disabling service workers
// https://web.dev/service-worker-lifecycle/#shift-reload
if (wbReg && navigator.serviceWorker.controller === null) {
console.error('detected ctrl+shift+r: reloading page')
location.reload()
throw new Error('page loaded with cache disabled: ctrl+shift+r')
}
Upvotes: 1
Reputation: 217
I was able to keep using the service worker even after Ctrl+F5 via the following approach:
In the window script:
navigator.serviceWorker.register(<...>).then (registration => {
if (navigator.serviceWorker.controller === null) {
// we get here after a ctrl+f5 OR if there was no previous service worker.
navigator.serviceWorker.ready.then(() => {
registration.active.postMessage("claimMe");
});
}
<...>
});
In the service script:
self.onmessage = (event) => {
if (event.data === "claimMe") {
self.clients.claim();
}
};
In short, we ask the service worker to claim all clients again, which works even for clients that used Ctrl+F5.
If you want to respect the Ctrl+F5 in the service worker code, you could either:
Upvotes: 6
Reputation: 3025
How to make ServiceWorker survive cache reset/Shift+F5?
Theorically (*), you can do it with js plugins which detect the key hit of Ctrl
or Shift
... then prevent the "force refresh" to happen
...but there is a story behind this Ctrl
/Shift
reload.
(*) disclaimer: I've not tried this yet
This is actually a spec of Service Worker. And only present in recent change of Chrome. For the earlier version of Chrome , Service Worker has no any issue surviving a "force refresh".
Along with the spec from W3C
navigator.serviceWorker.controller returns null if the request is a force refresh (shift+refresh).
Also, there are many people (**) has suggested that a "force refresh" should always clear out all kind of caches. Which is matched with the purpose of its existent and its spec.
...Furthermore, we even got it on the wikipedia...
Wikipedia: Bypassing your cache means forcing your web browser to re-download a web page from scratch
(**) us, web developers in the early stage of service worker.
In my opinion I think it is OK to let a force refresh doing its job. Since pretty much all of us always expecting the browser to not use any cache when we doing this.
Upvotes: 2