I want my Service Worker to behave just like a browser cache in some situations. That means when responding with a cache hit, I first need to make sure that the resource is not expired. I can do this like this for example:
const cacheControl = response.headers.get('cache-control');
const date = new Date(response.headers.get('date'));
const age = parseInt(response.headers.get('age') || '0', 10);
const maxAge = getMaxAge(cacheControl);
const expiration = date.getTime() + 1000 * (maxAge - age);
const isFresh = Date.now() < expiration;
I get the cache-control
, date
and age
header from the cached response, compute the expiration and compare to the current time.
The only problem with this approach is that it can be subject to clock drift between client and server. This is because the date header is generated on the server side but the final comparison is made with the local client time.
Imagin the client time is off by one day (which sadly happens sometimes), now the cache entries may be cached a day longer or shorter than intended.
My desired solution would be to add the fetch time as a custom header when storing the response in the cache. Then I could use this custom header instead of the
const networkResponse = fetch(request);
// does not work, headers are immutable
networkResponse.headers.append('x-time-fetched', Date.now());
cach.put(request, networkResponse);
Sadly, this solution does not work because the network response is not mutable. Btw: copying the response to add this additional information is not an option.
Does someone have an idea how to correctly identify stale cache entries like the browser?