Browser Cache Management - Ensure Updates

This post describes one way to ensure the javascript and CSS are requested by the browser when a new release is distributed.

The first approach is to prefix the file names with a version-release string, and create symlinks to the files during installation or the first execution. Many systems have a version identification mechanism.

To manage the symlinks, the following could be used:


        echo 'fclearold'
        for g in $(find *.$1 -maxdepth 1 -type l);do
                echo $g
                rm -f $g

        echo 'fcreatenew'
        for g in $(ls *.$1); do
                ln -s $g $2.$g


version=`cat "$BASE/config/version`;
for f in 'js' 'css'; do
        echo $f
        pushd $f > /dev/null
        fclearold $f
        echo $version;
        fcreatenew $f $version
        popd > /dev/null

fclearold removes the old symlinks, fcreatenew makes new ones. It is assumed the javascript is in the js directory and all javascript files have a .js extension, and the CSS is in the css directory and all CSS files have a .css extension.

httpd.conf (or equivalent)

# Cache js and CSS files for 6 months - with a timestamp
<FilesMatch "\.(js|css)$">
  ExpiresActive On
  ExpiresDefault "access plus 6 months"
  Header set Cache-Control "max-age=15552000"
  RewriteEngine On
  RewriteRule (.*)/[0-9]+\.(.*)$ $1/$2
  FileETag MTime

Timestamp Management Code (PHP)

        function sTimestamp()
                $sTimestampFile = 'cache/timestamp';
                if (is_file($sTimestampFile))
                        $sRetVal = file_get_contents($sTimestampFile);
                        $sRetVal = time();
                return $sRetVal;

Once the timestamp is set, it is cached in the cache/timestamp file. In this system, the cache is cleared when new releases are installed, so the absence of the timestamp file ensures an update and a new set of requested files.

The timestamp can applied to .js and .css file requests like so:

<script type="text/javascript" src="js/<?php echo $timestamp ?>.code.js"></script>