13

I have an app with a basic 'shell' of HTML, CSS and JS. The main content of the page is loaded via multiple ajax calls to an API that is at another URL to the one my app is running on. I have set up a service-worker to cache the main 'shell' of the application:

var urlsToCache = [
  '/',
  'styles/main.css',
  'scripts/app.js',
  'scripts/apiService.js',
  'third_party/handlebars.min.js',
  'third_party/handlebars-intl.min.js'
];

and to respond with the cached version when requested. The problem I am having is that the response of my ajax calls are also being cached. I'm pretty sure that I need to add some code to the fetch event of the service-worker that always get them from the network rather than looking in the cache.

Here is my fetch event:

self.addEventListener('fetch', function (event) {
    // ignore anything other than GET requests
    var request = event.request;
    if (request.method !== 'GET') {
        event.respondWith(fetch(request));
        return;
    }

    // handle other requests
    event.respondWith(
        caches.open(CACHE_NAME).then(function (cache) {
            return cache.match(event.request).then(function (response) {
                return response || fetch(event.request).then(function (response) {
                    cache.put(event.request, response.clone());
                    return response;
                });
            });
        })
    );
});

I'm not sure how I can ignore the requests to the API. I've tried doing this:

if (request.url.indexOf(myAPIUrl !== -1) {
  event.respondWith(fetch(request));
  return;
}

but according to the network tab in Chrome Dev Tools, all of these responses are still coming from the service-worker.

1
  • Why wouldn't it indicate the responses came from the service worker? Also, you can use string.includes. Commented Nov 20, 2015 at 20:48

1 Answer 1

25

You do not have to use event.respondWith(fetch(request)) to handle requests that you want to ignore. If you return without calling event.respondWith browser will fetch the resource for you.

You can do something like:

if (request.method !== 'GET') { return; }
if (request.url.indexOf(myAPIUrl) !== -1) { return; }

\\ handle all other requests
event.respondWith(/* return promise here */);

IOW as long as you can determine synchronously that you don't want to handle the request you can just return from the handler and let the default request processing to take over. Check out this example.

2
  • Thanks, I've done this. When I look in the network tab of the Chrome Devtools, I see each request twice: once is successful but the other is failed and the status is (Service Worker Failback). Any idea why this is?
    – Ben Thomas
    Commented Nov 24, 2015 at 14:52
  • Interesting. I don't see that (at least I think I don't) on our site. May be @jeff-posnick can chime in: check out his somewhat related response - can you reproduce that behavior with the example gist mentioned there?
    – pirxpilot
    Commented Nov 25, 2015 at 16:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.