how do I control caching for releases with PHP, headers, etc for a backbone project?

468 views Asked by At

So we are doing weekly releases of our project and we are running into problems with clients having old stale versions of certain files.

The stack is backbone with requirejs with backbone boilerplate and an Apache2 server with PHP backend.

We have the index html file that gets loaded, template HTML files that get loaded using AJAX, and then all the js files.

This question seems related to https://stackoverflow.com/questions/12103341/backbone-boilerplate-disable-caching but I didn't see a good answer there.

I've heard that cache-control headers and mod expires and mod headers for PHP might be helpful, but I don't know how to put it all together.

Essentially, what we want to do is make sure on a release of new code to the prod server that everything is not cached at least once. THen after that, normal caching to increase load speed would be ideal.

At the very least, I would liek to understand how to completely prevent these things from being cached.

Any ideas?

5

There are 5 answers

0
nxtwrld On BEST ANSWER

With requirejs, there is a parameter called urlargs it adds a parameter to all your requirejs requests and can be employed to force cache update. The example on the page use a timestamp, but you probably looking for a build version.

However, you should use r.js to build a production version of your scripts (it compiles and minifies all files loaded with require and produces a single library). This will reduce load time and save you a lot of worries. You would them link just this one library and have the build version in the file name itself (something like backbone.app.1.0.23456.js).

1
Bryan Allo On

I've found it difficult to control the user client's browser as far as caching is concerned. One trick I've used in the past is to append a random number to my JS file URL. Like

<script src="https://www.mydomain.com/myjsfile.js?123456789"></script>

OR

<script src="https://www.mydomain.com/myjsfile.js?releaseID=123456789"></script>

That causes the client to treat it as a new file altogether. You could assign a random number to each release and that should cause your users' browsers to pull the new JS file again. Same applies to CSS.

I hope this helps. Good luck.

0
Alex On

Appending random number to the uri breaks client caching.
Instead, append the file's last modification time.

<script src="myjsfile.<?=filemtime('myjsfile.js')?>.js"></script>

Handling that would require and .htaccess rule, such as

RewriteRule ([^/]*)\.[0-9]*\.css$ $1.css [L,NC]

And additionally, provide .htaccess with long term caching instructions

<IfModule mod_expires.c>
  ExpiresActive on
  ExpiresByType text/css                  "access plus 1 year"
  ExpiresByType application/javascript    "access plus 1 year"
</IfModule>
0
Lars On

The caching of files on the client side is defined by two values: a meta-information in the <head>-section of the called html file and an HTTP-Header.

In the HTML file you may give the two meta-tags cache-control and expires to define a weekly expiration date by giving a simple php-command:

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="PRIVATE">
<?php
    $daysDelta = 7-date("w");
    $expiration = date(DATE_RFC1123, mktime(0, 0, 0, date("m"), 
        date("d")+$daysDelta+1, date("Y")));
?>
<META HTTP-EQUIV="EXPIRES" CONTENT="<?= $expiration ?>">

This would kill the cache on Monday morning. Another method would be the cache setting via HTTP-Header:

<?php
    header("Cache-Control: private");
    header("Expires: <?= $expiration ?>");
?>

Using both methods, you will have caching during the week, but after weekend, the clients will invalidate their caches and repull the data.

0
Sachin Prasad On

To remove caching from a page you need to include this at the top of your page:-

$this->output->set_header("Expires: Tue, 01 Jan 2000 00:00:00 GMT"); 
$this->output->set_header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
$this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); 
$this->output->set_header("Cache-Control: post-check=0, pre-check=0", false); 
$this->output->set_header("Pragma: no-cache");