How to ignore url querystring from cached urls when using workbox?

5.6k views Asked by At

Is there a way to ignore query string "?screenSize=" from below registered route using workbox! If I can use regex how would i write it in below scenario? Basically, I am looking to match the cache no matter what is the screenSize querystring.

workboxSW.router.registerRoute('https://example.com/data/image?screenSize=980',
workboxSW.strategies.cacheFirst({
    cacheName: 'mycache',
    cacheExpiration: {
        maxEntries: 50
    },
    cacheableResponse: {statuses: [0, 200]}
})
);

After trying the cachedResponseWillBeUsed plugin: I do not see the plugin is applied: enter image description here

5

There are 5 answers

8
Jeff Posnick On

Update: As of Workbox v4.2.0, the new cacheKeyWillBeUsed lifecycle callback can help override the default cache key for both read and write operations: https://github.com/GoogleChrome/workbox/releases/tag/v4.2.0

Original response:

You should be able to do this by writing a cachedResponseWillBeUsed plugin that you pass in when you configure the strategy:

// See https://workboxjs.org/reference-docs/latest/module-workbox-runtime-caching.RequestWrapper.html#.cachedResponseWillBeUsed
const cachedResponseWillBeUsed = ({cache, request, cachedResponse}) => {
  // If there's already a match against the request URL, return it.
  if (cachedResponse) {
    return cachedResponse;
  }

  // Otherwise, return a match for a specific URL:
  const urlToMatch = 'https://example.com/data/generic/image.jpg';
  return caches.match(urlToMatch);
};

const imageCachingStrategy = workboxSW.strategies.cacheFirst({
  cacheName: 'mycache',
  cacheExpiration: {
      maxEntries: 50
  },
  cacheableResponse: {statuses: [0, 200]},
  plugins: [{cachedResponseWillBeUsed}]
});


workboxSW.router.registerRoute(
  new RegExp('^https://example\.com/data/'),
  imageCachingStrategy
);
0
aw04 On

To build on the other answer, caches.match has an option ignoreSearch, so we can simply try again with the same url:

cachedResponseWillBeUsed = ({cache, request, cachedResponse}) => {
  if (cachedResponse) {
    return cachedResponse;
  }

  // this will match same url/diff query string where the original failed
  return caches.match(request.url, { ignoreSearch: true });
};
0
Kovács Gergely On

You can use the cacheKeyWillBeUsed simply, modifying the saved cache key to ignore the query at all, and matching for every response to the url with any query.

const ignoreQueryStringPlugin = {
 cacheKeyWillBeUsed: async ({request, mode, params, event, state}) => {
  //here you can extract the fix part of the url you want to cache without the query
  curl = new URL(request.url);
  return curl.pathname;

 }
};

and add it to the strategy

workbox.routing.registerRoute(/\/(\?.+)?/,new 
 workbox.strategies.StaleWhileRevalidate({
  matchOptions: {
   ignoreSearch: true,
  },
  plugins: [
   ignoreQueryStringPlugin
  ],
}));
0
Hajopa On

As of v5, building on aw04's answer, the code should read as follows:

const ignoreQueryStringPlugin = {
    cachedResponseWillBeUsed: async({cacheName, request, matchOptions, cachedResponse, event}) => {
        console.log(request.url);
        if (cachedResponse) {
            return cachedResponse;
        }

        // this will match same url/diff query string where the original failed
        return caches.match(request.url, {ignoreSearch: true});
    }
};
registerRoute(
    new RegExp('...'),
    new NetworkFirst({
        cacheName: 'cache',
        plugins: [
            ignoreQueryStringPlugin
        ],
    })
);
0
kudlohlavec On