4
votes

I'm trying to cache a single page webapp with a service worker. It should get all it's files from the cache and update that cache only when a new service worker-version is published.

With a precache function i'm writing some files to the cache as follows:

function precache() {
return caches.open(CACHE).then(function(cache) {
    return cache.addAll([
        'index.html',
        'js/script.js',
        'img/bg.png',
        'img/logo.svg',
        ...
    ]);
});
}

(I've tried to cache with and without "/" before the paths, and even with absolute paths. Makes no difference)

In Chrome's Cache Storage, the content of all those files is exactly as it should be. But when I try to serve the files from cache on reload of the page, none of the requests match with the cache, they all get rejected, even when I'm still online.

self.addEventListener('fetch', function(evt) {
    evt.respondWith(
        caches.match(evt.request).then(function(response) {
            if(response){
                return response;
            } else {
                reject('no result');
            }
        }).catch(function(){
            if(evt.request.url == 'https://myurl.com'){
                return caches.match('/index.html');
            }
        });
    )
});

The index.html from the catch-function gets served correctly, and in turn requests the other files, like /js/script.js. Those request show up like this in the console:

Request { method: 'GET', url: 'https://myurl.com/js/script.js', ... referrer: 'https://myurl.com' }

But they do not return a response, only a notice like this shows:

The FetchEvent for "https://myurl.com/js/script.js" resulted in a network error response: an object that was not a Response was passed to respondWith().

Am I missing something here?

2
from the error - there is a type mismatch... ie u have objs in the cache but they r of wrong type -- not =ResponseRobert Rowntree
According to developer.mozilla.org/en-US/docs/Web/API/Cache/match .match doesn't return a failed promise. If there is not a match it resolves to undefined. You can probably just move your catch to the then block with if (!response && url == 'https://myurl.com') and then else return response`Rajit
@Rajit thank you for pointing me to that documentation! The catch statement didn't give me more information, but the docs pointed me to the options argument for the match-statement, which solved the problem. I've answered my question for future reference.Duncan

2 Answers

4
votes

Thanks to the link from Rajit https://developer.mozilla.org/en-US/docs/Web/API/Cache/match I've found that the caches.match() function accepts an options-object.

I've updated that line in my service worker to

caches.match(evt.request,{cacheName:CACHE,ignoreVary:true}).then(function(response) {

so it includes the cache-name and an ignores VARY header matching, and now it returns the correct files.

3
votes

I had the same problem and it seems to have been solved by using the ignoreVary:true parameter. The documentation explicitly states that the cacheName parameter is ignored by Cache.match()