Search code examples
javascriptbrowser-cacheweb-workerservice-worker

Use ServiceWorker cache only when offline


I'm trying to integrate service workers into my app, but I've found the service worker tries to retrieve cached content even when online, but I want it to prefer the network in these situations. How can I do this? Below is the code I have now, but I don't believe it is working. SW Install code is omitted for brevity.

var CACHE_NAME = 'my-cache-v1';
var urlsToCache = [
  /* my cached file list */
];

self.addEventListener('install', function(event) {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

/* request is being made */
self.addEventListener('fetch', function(event) {
  event.respondWith(
    //first try to run the request normally
    fetch(event.request).catch(function() {
      //catch errors by attempting to match in cache
      return caches.match(event.request).then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
      });
    })
  );
});

This seems to lead to warnings like The FetchEvent for "[url]" resulted in a network error response: an object that was not a Response was passed to respondWith(). I'm new to service workers, so apologies for any mistaken terminology or bad practices, would welcome any tips. Thank you!


Solution

  • Without testing this out, my guess is that you're not resolving respondWith() correctly in the case where there is no cache match. According to MDN, the code passed to respondWith() is supposed to "resolve by returning a Response or network error to Fetch." So why not try just doing this:

    self.addEventListener('fetch', function(event) {
      event.respondWith(
        fetch(event.request).catch(function() {
          return caches.match(event.request);
        })
      );
    });