I've been stuck in caching hell for the past couple of days and while I'm starting to get it still struggling a little bit.
Desired Result
I want to include a JS file on a site and have it cached and/or only fetch a new copy of the file when the file has been changed on the server. I DO CANNOT use version tags or hashes in the file name. The file name needs to stay consistent.
Where I'm at
From what I understand after reading up on this using Etags are the perfect solution for this. They will update when the file is changed and will send the new version of the file if tags don't match. And this seems to work when I request the file via the browser
So you can see that on first request i get a 200 and download size is 292 B and on second request because tags match I get a 304 and download size is 137 B (Just header size I assume). Great! This is exactly what I want.
My request header with looks for the etag:
My Problem
Now this works when I request the file from the browser, but adding a js file in a script tag doesn't send request headers the same way. So, opening the following html file
<!DOCTYPE html>
<html>
<body>
<script src="https://myTestSite.com/testCache.js">
</script>
</body>
</html>
My js file is fetched every time because the if-none-match
request header is not present. How do I replicate the behavior that was observed in the above scenario when using html script tag?
TL;DR
How do I use Etags to request only modified JS files when using html script tags and not simple browser GET request?
I got it working but not completely as I had expected it to. Here's what I ended up doing.
In the directory where I wanted to serve my js file from I added an .htaccess file
<FilesMatch "\.(js|css)$">
Header set Cache-Control "no-cache, must-revalidate"
</FilesMatch>
I realized that if I was locally adding my js files to cache it would always pull from the local cache and never even make the request to the server. So, even if the Etag had been changed my client would never know because the file was already locally cached.
So, I decided to not cache the file at all and revalidate. So, while I do have a slight overhead of the http headers, I will always get the latest file without needing to fetch the whole file every single time.
Another option (and maybe simpler) is to add a random querystring to the end of your resource URI:
<script src="https://myTestSite.com/testCache.js?version=<random_value>"></script>
This still means you are fetching the same file from the server (server will ignore the querystring when returning the resource) so you do not have to change anything on your backend.
The random value may be auuid
, this will ensure randomness. Also the key maybe anything not necessarily version
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With