Clear Browser Cache after Version Upgrade

Asked

Viewed 6,498 times

4

I have the following scenario:
Each month we release new versions for our customers, and a lot of the time our customers call in saying that X functionality isn’t working the way it should. Because it is normally running a function that is of the previous version exactly because of the browser cache, in which case the client has to click CTRL+F5 or even clear all its cache for the X functionality to work properly.

I wonder if there is a class in php or in another language too that can be implemented in php to perform the cleaning of this cache.
because for such situation I can use the database to verify if we are climbing version for the customer or not and run the cleaning of this browser.

Good today we cache all JS to earn a little extra in performance, we use the following:

header("Pragma: public");
header("Expires: 31536000");
header("Cache-Control: must-revalidate, post-check=900, pre-check=3600");
header("Cache-Control: public");
header("Content-Type: application/javascript");
header("Cache-Control: public, max-age=31536000");

I searched a lot over the internet, and everyone I looked for did not succeed in what I was actually wanting to run, last tried the proper php function

Clearstatcache()

  • I believe that by adding Last-Modified the problem is solved. This will inform the browser which date the file was changed, which in your case would be the date the new version became available. So the browser would not use the cached version but the server version.

5 answers

4


It is enough that the name of the JS and CSS file or files has a variable name.. For example:

  • What you should have now: omeucss.css || omeujs.js
  • What you should get: omeucssv12 || omeujs45.js

This can be done automatically, depending on your system.. i join all js in one file (like css) and in html I call the url: meusite.pt/js/ when it calls the file /js/omeujs.js At that moment it sees if the file has already been generated, if it has not been generated (taking into account the variable) and displays the result js :)

EDITE

I forgot the htaccess part:

RewriteRule ^js/(.+).js$ /js/ [NC,L]

Hug and good luck!

  • use very similar technique, only instead of changing the file name I only pass another value as parameter type $LAB.script('../js/js_1.9/jquery-1.8.2.js?nocache='+Math.random())

  • Yes, it would be the easiest way up, good comment ;) The way I talked to small things is able to give more work.. I use it like this because I have other things running in js controller...

  • The two techniques worked for me thanks

  • @Paulohenrique The solution is valid, but you don’t want to cache the scripts? Imagine one version is released today and another will be released in 2 months. Every time someone makes a request to the server, the JS file will be sent since the reply to the request will not be a 304, IE, It collapses any cache system.

  • @Filipemoraes Yes, but the global JS files are two situations, such as jquery-1.9.2.js and the custom.js files that in my case custons were caching which caused me a problem but I created a function where it adds a parameter at the end of JS files that are different from global entries, and worked the way I would like, that is to say all global files cache but custom ones that are constantly changing do not enter, I lose a little when the custons are not changed and yes it is a mistake but I will study this flaw more calmly :D much obr master

4

Solution

  • Rename the extensions of all JS files (which I believe are the files causing caching problems) to . php
  • Set the content type of the JS page using header("Content-type: text/javascript");
  • Create a PHP script responsible for validating whether or not to clear the cache.

To validate whether or not it is necessary to clean the cache, you can use cookies.

<?php

$versaoAtual = 1;

if (!isset($_COOKIE['versao'])) {
    setcookie('versao', $versaoAtual, (time() + (60 * 24 * 3600)));
} else {
    $versao = (int) $_COOKIE['versao'];

    if ($versao < $versaoAtual) {
        header("Pragma: no-cache");
        header("Expires: Mon, 20 Jul 2000 03:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: no-cache, cachehack=" . time());
        header("Cache-Control: no-store, must-revalidate");
        header("Cache-Control: post-check=-1, pre-check=-1", false);

        setcookie('versao', $versaoAtual, (time() + (60 * 24 * 3600)));
    }
}

That’s it, I believe that solves your problem. Remember to always update the value of the variable versaoAtual, because it is based on it that PHP will decide whether the client needs to clear the cache.

Extra

I believe (I’m not sure), that you could also use Cloudflare for this. In their dashboard you have an option purge cache, where you define which files you want to remove from the cache.

This would remove the Cloudflare server cache, I just don’t know if I would remove it from the client as well, I haven’t had time to analyze how this cache purge works.

That’s it, I hope I contributed somehow.

  • @Filipemoraes, the header function sends instructions to the client’s browser.

  • Yes yes, I’m sorry, I deleted the comment, but the system above it has implemented, at least what I realized. The problem would be solved if it added the header Last-Modified, informing the browser of the latest file modification.

3

No header combination is 100% guaranteed.

The most guaranteed is to add a parameter as a url query.

Example: /js/arquivo.js?20160227.

This ensures that when modifying, the new version will always be downloaded. Just modify the number. In this case we use date.

Suppose tomorrow you change it again, then you change it to /js/arquivo.js?20160228.

Browser caching exists to reduce data traffic, saving bandwidth. In this scheme, using a new parameter for each new version, you will ensure that the cache keeps the current version and you will always be sure that a new version will always be updated, regardless of the browser cache.

Instead of using current date, you can also use the file version.

Example: /js/arquivo.js?1.0.0.2.

You can also use anything random, as long as you don’t repeat an old one already used.

Example: /js/arquivo.js?qualquer_coisa_serve.

2

I believe that by adding Last-Modified the problem is solved.

This will inform the browser which date the file was changed, which in your case would be the date the new version became available.

Therefore, the browser would not use the cached version but the server version. The cached version would be replaced by the server version. Changing the code entered in the question:

//mktime(hora, minuto, segundos, mes, dia, ano)
//Abaixo indicamos que houve uma alteração no ficheiro a meia noite do dia 26/02/2016 
$newVersion = gmdate("M d Y H:i:s", mktime(0, 0, 0, 2, 26, 2016));

header("Pragma: public");
header("Expires: 31536000");
header("Last-Modified: " . $newVersion . " GMT");
header("Cache-Control: must-revalidate, post-check=900, pre-check=3600");
header("Cache-Control: public");
header("Content-Type: application/javascript");
header("Cache-Control: public, max-age=31536000");

-1

The problem not only the CSS or JS the issue is cache of the browsers for any page be html or php the solution is as follows:

index.php? <php echo time(); > output index.php? 1625147922

can also put in css and js example.css? <php echo time(); > example.js? <php echo time(); > Life browsers will always have new pages or content.

In short: when opening the page the browser will understand that it is a new url

Browser other questions tagged

You are not signed in. Login or sign up in order to post.