Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
385 views
in Technique[技术] by (71.8m points)

caching - Using multiple javascript service workers at the same domain but different folders

My website offers an array of web apps for each client. Each client has a different mix of apps that can be used.

Each web app is a hosted in a different folder.

So I need to cache for each client only it's allowed web apps instead of caching all the apps, many of them he the user, will not use at all.

I naively created a global service worker for the shell of the website and custom named service worker for each folder or app.

However I noticed that after the first service worker, say sw_global.js service worker registers, installs, activates, fetches succesfully and creates a cache named cache-global, the second service worker, say sw_app1,js, which creates it's own cache cache-app1, clears all cache-global.

How can I use custom service worker for each folder?. Please keep in mind that each folder is a microservice or a web app which is not necesarilly allowed for all users, so it's imperative to not cache all content from a unique service worker.

Actually I code on vanilla.js, no angular, no react, no vue, no nada.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There's two things to keep in mind here:

  1. It's possible to register an arbitrary number of service workers for a given origin, as long as each service worker has its own unique scope. It sounds like you're doing this already, registering both a top-level service worker with a scope of / and then additional service workers scoped to the paths from which each of your independent web apps run.

  2. The Cache Storage API (and other storage mechanisms, like IndexedDB) are shared throughout the entire origin, and by default there's no "sharding" or namespace segregation.

Taking those two facts together, my guess is that what's happening is that you have some cache cleanup code in the activate handler of one of the service workers that's scoped to a specific web app, and that code retrieves a list of current cache names and deletes any caches that it thinks is out of date. That's a common thing to do in a service worker, but you can run into trouble if you don't take into account the fact that caches.keys() will return a list of all the caches in your origin, even the caches that were created by other service worker instances.

Assuming that's what's going on here, a model that I'd recommend following is to include the value of registration.scope as part of the cache name when you create your caches. When it comes time to delete old cache entries in your activate handler, it's easy to make sure that you're only cleaning up caches that your specific service worker is supposed to manage by filtering out those that don't match registration.scope.

E.g., something like this:

const CACHE_VERSION = 'v2';
const CACHE_NAME = `${registration.scope}!${CACHE_VERSION}`;

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => {
      // Add entries to the cache...
    })
  );
});

self.addEventListener('activate', (event) => {
  const cleanup = async () => {
    const cacheNames = await caches.keys();
    const cachesToDelete = cachesNames.filter(
        (cacheName) => cacheName.startsWith(`${registration.scope}!`) &&
                       cacheName !== CACHE_NAME);
    await Promise.all(cachesToDelete.map(
      (cacheName) => caches.delete(cacheName)));
  };

  event.waitUntil(cleanup());
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...