Skip to content
Advertisement

How to access cache web storage in service worker in the client?

I’m figuring out how to access data stored in service worker web cache. My service worker looks like this:

self.addEventListener('install',(e) => {
    e.waitUntil(
        caches.open(astroCacheName).then(c => {
            return Promise.resolve(c.addAll([
                    './',
                    './css/normalize.css',
                    './css/main.css',
                    './js/index.js',
                    './js/discovery.js',
                    'http://localhost:4050/planets',
                    'http://localhost:4050/stars',
                    'http://localhost:4050/galaxies'
                ]))
        }))
})
self.addEventListener('fetch',(e) => {
    e.respondWith(
        caches.match(e.request).then(r => {
            return r || fetch(e.request)
        }))
})

self.addEventListener('activate', function (e) {
    console.log('activate event')
  e.waitUntil(caches.keys().then(function (cacheNames) {
    return Promise.all(cacheNames.map(cache => {
      if (cache !== astroCacheName) {
        console.log('Service Worker: Clearing Old Cache')
        return caches.delete(cache)
      }
    }))
  }))
})

Where the three las ones URLS inside the event ‘install’ are request to my server which responds with JSON that I need to access in the client. They’re stored correctly in the cache. Then, how can I have access to this data in the client?

Answer

There are two different ways that you can “access” responses that are cached by a service worker from within a window client. One of them is more direct than the other, and the specific approach you use should tailored to your use case.

Indirect cache access, via fetch()

If there is a service worker in control of a specific window client (i.e. a web page), then any network request will trigger that service worker’s fetch event handler, and give your service worker a chance to generate a response. The fetch event handler in the service worker code you provided uses caches.match(e.request) to attempt to lookup a cached response first, falling back to the network if that’s not possible. So from your web page, if you call fetch('/planets'), the response you get back from the service worker will end up coming from the cache.

If there’s a cache miss (given the fetch event handler in your current service worker), or if the request is made before the service worker has taken control of the window client, the fetch('/planets') request will end up being fulfilled by the network. That will be more resilient.

Direct cache access, via caches.match()

The same Cache Storage API that’s exposed inside of a service worker’s global scope is also available in the window global scope. This means that if you’ve already installed a service worker, and that service worker has populated your caches, you can use caches.match('/planets') directly from the context of your web page to obtain the cached Response object.

This approach might be useful if you want a guarantee that the response you’re getting is from the cache (as opposed to a response from the network due to a cache miss). The flipside of that is that you’ll only get a response back if the service worker has already completed installation, and there’s no fallback if that hasn’t happened yet.

Sometimes this is appropriate, though, if you’re, e.g., attempting to only display data that’s already been cached.

Advertisement