Evading far future expires!

I use rsync to sync files between my computer and my webserver. When I make changes to the static content (mostly css or javascript files), most users still see the cached versions in their browsers thanks to my far futures expires header following advice from yslow.

From what I understand, with a far future expires header, the browser simply loads that content from cache (till it expires) without contacting the server. It would probably have gotten a ’304 – Not Modified’ response anyway. So, you save an HTTP request and the little processing required to verify if both parties have the same file (see ETags)

So, back to my problem with browsers using the old file (by respecting the far future expires header) instead of the new one I just uploaded. Theres two ways to get the browser to load the latest file. Either the page has to be refreshed without cache (by pressing the refresh button, or ctrl+f5 in most browsers) or you’ll have to use a different filename in the html and also rename the file on your server. Waiting for all your users to refresh the page is not a good idea :)

What I do is add a version number (usually the date of update) to the filename within the html and get the webserver (lighttpd in my case) to serve the current file no matter what the version. For example, Instead of

<script src=”/js/filename.js”></script>

I use

<script src=”/js/filename.20101222.js”></script>

The webserver will serve the same filename.js file whether you use filename.20101222.js or filename.20050101.js, but the browser will now be using the current version of the file and this will also cache this file until you update again.

I use lighttpd and here is the config ( for filename.{version}.js )

url.rewrite = (“^/js/([a-zA-Z0-9/]*).([0-9]*).js$” => “/js/$1.js”)

If you want it to be /js/{version}/filename.js

url.rewrite = (“^/js/([0-9]*)/([a-zA-Z0-9/]*).js$” => “/js/$2.js”)

I use only numbers (dates as yyyymmdd), hence the [0-9]. Adjust the regex to whatever versioning you plan to use.

I’m not used to apache, but I’m guessing this is what the settings would look like on it

RewriteRule         ^/js/([a-zA-Z0-9/]*).([0-9]*).js$        /js/$1.js

RewriteRule         ^/js/([0-9]*)/([a-zA-Z0-9/]*).js$         /js/$2.js

One thought on “Evading far future expires!

Leave a Reply