Reputation: 13009
I'm using a service worker to cache a response from a remote server into a runtime cache, based on the example service worker code here: https://googlechrome.github.io/samples/service-worker/basic/
I'd like to do this as efficiently as possible because there is a lot in the URL that has no effect on the returned content (only on how the response is generated at the server), so the URL used for caching purposes can be different to that used for fetching purposes.
For example, the following two URLs return exactly the same content:
https://example.com/{"a":"whatever","b":"matters"}
https://example.com/{"a":"anything","b":"matters"}
but the following returns something different:
https://example.com/{"a":"anything","b":"different"}
So for caching purposes we could strip out {"a":"anything"}
from the URL, but for fetching that information should be retained in the URL.
I'm new to service workers and am struggling to see how I can achieve this.
Upvotes: 1
Views: 1029
Reputation: 56064
First off, those are... odd looking... URLs, but I'll take you at face value and assume that you're actually including serialized JSON as the path of a URL. (I'd recommend doing something like URL encoding it and using it as a query parameter, rather than in the path, but that's not relevant to your answer.)
In any case, when looking up an entry using the Cache Storage API, you have complete control over which URL is used as the cache key that gets passed to match()
. So you can normalize the incoming URLs passed in to a fetch
event handler to strip out anything you don't want before passing it in to match()
. You'd want to make sure that when you add entries to the cache, the URLs you use will follow the same format as the URLs that you use for lookups.
Here's an example:
// Assume that 'https://example.com/{"b":"different"}' is a cached URL.
self.addEventListener('fetch', event => {
// You'd probably want some sort of if() statement here so that
// you only respond with this normalized URL under certain conditions.
const normalizedUrl = normalizeUrl(event.request.url);
event.respondWith(caches.match(normalizedUrl));
});
function normalizeUrl(urlString) {
const urlObject = new URL(urlString);
// This assumes that the path of your incoming
// URL contains serialized JSON data, without the leading '/'.
const jsonString = urlObject.pathname.substring(1);
const jsonData = JSON.parse(decodeURIComponent(jsonString));
// Repeat this with any other properties you want to remove.
jsonData.a = undefined;
urlObject.pathname = JSON.stringify(jsonData);
return decodeURI(urlObject.toString());
}
But like I said, this is a pretty odd thing to do. Hopefully the general concept of being able to modify the cache key and return whatever cached entry you want is helpful, but I wouldn't use code like this in a production system.
Upvotes: 2