I have a page /data.txt
, which is cached in the client's browser. Based on data which might be known only to the server, I now know that this page is out of date and should be refreshed. However, since it is cached, they will not re-request it for a long time (until the cache expires).
The client is now requesting a different page /foo.html
. How can I make the client's browser re-request /data.txt
and update its cache?
This should be done using HTTP or HTML (not all clients have JS).
(I specifically want to avoid the "cache-busting" pattern of appending version numbers to the /data.txt
URL, like /data.txt?v=2
. This fills the cache with useless entries rather than replacing expired ones.)
Edit for clarity: I specifically want to cache /data.txt
for a long time, so telling the client not to cache it is unfortunately not what I'm looking for (for this question). I want /data.txt
to be cached forever until the server chooses to invalidate it. But since the user never re-requests /data.txt
, I need to invalidate it as a side effect of another request (for /foo.html
).
CodePudding user response:
The first step is to fix your cache headers on the data.txt resource so it uses your desired cache policy (perhaps Cache-Control: no-cache
in conjunction with an ETag
for conditional validation). Otherwise you're just going to have this problem over and over again.
The next step is to get clients who have it in their cache already to re-request it. In general there's no automatic way to achieve this, but if you know they're accessing foo.html then it should be possible. On that page you can make an AJAX request to data.txt with the Cache-Control: no-cache
request header. That should force the browser to bypass the cache and get a fresh version, and the cache should then be repopulated with the new version.
(At least, that's how it's supposed to work. I've never tried this, and I've seen reports here that browsers don't handle Cache-Control
request headers properly.)
CodePudding user response:
To expand my comment:
You can use IF-Modified-Since
and Etag
, and to invalidate the resource that has been already downloaded you may take a look at the different approaches suggested in Clear the cache in JavaScript and fetch(), how do you make a non-cached request?, most of the suggestions there mentioned fetching the resource from JavaScript with no-cache header fetch(url, {cache: "no-store"})
.
Or, if you can try sending a Clear-Site-Data
header if your clients' browsers are supported.
Or maybe, give up this time only for the cache-busting
solution. And if it's possible for you, rename the file to something else rather than adding a querystring as suggested in Revving Filenames: don’t use querystring.
Update after clarification:
If you are not maintaining a legacy implementation with users that already have /data.txt
cached, the use of Etag
And IF-Modified-Since
headers should help.
And for the users with the cached versions, you may redirect to: /newFile.txt
or /data.txt?v=1
from /foo.html
. The new requests will have the newly added headers.