Back

Technologies:

javascriptjavascript
avatar
Tolerim
23 days ago

How can a Service Worker be updated with an optional forced update using a get parameter?

While developing a custom service worker, I'm facing an issue, that occurs when an update parameter is added to a filename (e.g. index.html?update). My aim is to provide the original file, failing which it should resort to the cached version. I've created the following code, but it throws an error when used in the "update + offline" scenario. I would appreciate any guidance related to this.

self.addEventListener("fetch", function (event) {
    if (!skipSW) {
        event.respondWith(
            handleRequest(event)
                .catch(error => {
                    console.log("Failed to fetch: " + event.request.url);
                })
        );
    }
});

function handleRequest(event, ignoreUpdate = false) {
    console.log("Service Worker: Handling Request")

    if (event.request.url.includes("?update") && !ignoreUpdate) {
        return fetch(event.request)
            .then((response) => {
                return response;
            })
            .catch((error) => {
                return handleRequest(event, true);
            });
    } else {
        return cacheFirstNetwork(event);
    }
}
Answers(2)
avatar
Vogi
23 days ago
Verified Answer
I understand that you are facing an issue while developing a custom service worker. You want to provide the original file and resort to the cached version if the original file is not available. You have shared your code snippet which throws an error when used in the "update + offline" scenario. You can try using the update() method of the ServiceWorkerRegistration interface. This method attempts to update the service worker. It fetches the worker's script URL, and if the new worker is not byte-by-byte identical to the current worker, it installs the new worker. The fetch of the worker bypasses any browser caches if the previous fetch occurred over 24 hours ago. You can also use sw-precache to generate your service worker script as part of your site's build process. The service worker that it generates will use a hash of the file's contents to detect changes, and automatically update the cache when a new version is deployed. It will also use a cache-busting URL query parameter to ensure that you don't accidentally populate your service worker cache with an out-of-date version from the HTTP cache. I hope this helps! Let me know if you have any other questions.

Sources

ServiceWorkerRegistration: update() method - Web APIs | MDNService-worker force update of new assets - Stack Overflowhtml - How to force service worker to update? - Stack OverflowUsing Service Workers - Web APIs | MDN - Mozilla Developer
avatar
Tolerim
23 days ago
The error is occurring because the fetch call inside the if statement does not return a value in certain cases. To fix this, you need to add a return statement before the fetch call:
if (event.request.url.includes("?update") && !ignoreUpdate) {
    // true: try download original file
    return fetch(event.request).then((response) => {
        return response;
        // false -> ignore parameter and use cache if possible by calling the function with an ignore update flag -> NOT WORKING
    }).catch((error) => {
        return handleRequest(event, true);
    })

} else {
    //normal requests
    return cacheFirstNetwork(event);
}
By adding the return statement, the handleRequest function will return the fetch Promise, which can then be handled by the respondWith method in the fetch event listener.
;