Force javascript file update without disabling cache

In a large-scale web application that I develop a disorder occurs every time updates happen, because browsers, especially Google Chrome, make cache of JavaScript files and, sometimes, incompatibilities occur between the server and client code, leading to unforeseen situations and errors.

We have already considered versioning our JavaScript files so that their name carries the version number, thus making the browser consider them new files, but this proved unfeasible due to the large amount of files that exist and the confusion that this causes in our versioner (GIT).

Is there a pattern or solution that forces JavaScript to reload every time it is changed, without the user having to give a CTRL+F5 or clear the cache ? It is also not an option to disable the cache of pages.

Author: Marcus Vinicius, 2015-06-10

4 answers

Hello.

There is a technique called "Phantom Querystring" that solves this problem in most browsers.

In PHP is done like this:

<link href="/file-css.css?<?php echo time(); ?>" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/file-javascript.js?<?php echo time(); ?>"></script>

Rendering:

<link href="/file-css.css?1433981258" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/file-javascript.js?1433981258"></script>

This generates a different URL on each " F5 " and forces the browser to download the file again.

This technique is used to not have to change the header settings of the web server.

Update

The above solution may cause two problems:

1º) increased internet traffic from the web server.
2º) the web application loads more slowly because it does not use the benefits of the browser cache.

So to solve these two problems there are two solutions.

1st solution:

Create a constant that would be updated only when CSS and JS files change versions.

In ASP.NET:

Put On The Web.config a constant that indicates the version:

  <appSettings>
    <add key="Version" value="1254"/>
  </appSettings>

On The Site.Master put:

<link href="/file-css.css?<%= ConfigurationManager.AppSettings["Version"] %>" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/file-javascript.js?<%= ConfigurationManager.AppSettings["Version"] %>"></script>

In PHP:

It is recommended that the constant " VERSION "be created in a file of the type" config.php". But I put it here just for demonstration:

<?php
define('VERSION', '1254');
?>
<link href="/file-css.css?<?php echo VERSION; ?>" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/file-javascript.js?<?php echo VERSION; ?>"></script>

The two programming languages generate the same result in HTML:

<link href="/file-css.css?1254" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/file-javascript.js?1254"></script>

2nd solution

Write the HTML itself by changing the numbering "1254" only when the CSS and JS files change version.

The latter solution I consider the easiest.

References: Prevent your CSS and JavaScript Files From Being Cached

 18
Author: Deividson Damasio, 2019-10-02 22:30:31

As you are using ASP.NET, just use the features of Bundling . It will manage this for you, creating a different URL only when there is a new version of JavaScript, otherwise it will guide browsers to recover from cache-http 306.

When creating a project ASP.NET with template in Visual Studio, in the App_Start folder, you will have a file named BundleConfig.cs.

In it you configure the script groups or styles that will be published in the page.

public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/scripts/jquery").Include(
                "~/scripts/jquery-{version}.js"));

            bundles.Add(new ScriptBundle("~/scripts/meus-scripts").Include(
                "~/scripts/meuscript1.js",
                "~/scripts/meuscript2.js"));

            bundles.Add(new StyleBundle("~/content/site").Include(
                "~/content/site.css"));

#if DEBUG
            BundleTable.EnableOptimizations = false;
#else
            BundleTable.EnableOptimizations = true;
#endif

        }
    }

In its views , consumes passing the name of the groupings:

<html>
<head>
@Styles.Render("~/content/site")
</head>
<body>
    <!-- conteudo -->
    @Scripts.Render("~/scripts/jquery")
    @Scripts.Render("~/scripts/meus-scripts")
</body>
</html>
 3
Author: Thiago Lunardi, 2016-06-22 13:43:09

Marcus Vinicius , taking the idea of Dadeke (Phantom Querystring) and incrementing a little, I came up with the following solution. Add a: <?php echo filemtime("includes/script.js"); ?>, this way when updating the script file.js, it will automatically change the 'querystring'.

Final Result:

    <script src="script.js?"<?php echo filemtime("script.js"); ?>></script>
 1
Author: Washington Lacerda, 2017-04-13 12:59:44

This example needs a join between: database + JQuery + Json + ASP Classic( replace with your programming language) + HTML

Create a simple table in the database:

Tabela: atualize_me
Colunas: id( int, auto_increment ), status( bit, valor padrão: 1 )
Efetue um INSERT: insert into atualize_me(status) value(1)

Put in the file (in my case file.js) main that runs on every page of the site, the following information below:

$(document).ready(function(){
        // SE TIVER ALGUMA ATUALIZAÇÃO É SÓ IMPLEMENTAR 1 NO STATUS
        $.getJSON('json/json_atualize_me.asp',function(data){
                if( data[0].status == true ){
                        $.post('acao/json_atualize_me2.asp',{ status : 0 },function(data2){
                                window.location.reload(true);
                        });
                }else{  /* se quiser coloque algo aqui */ }
        });
});

Json_uptualize_me page content.asp:

<!--#include file="json_query.asp"--> ( veja mais informações sobre este arquivo )
<%
sql = "select status from "&bd_&".atualize_me;"
QueryToJSON(conn,sql).Flush
%>

Page content json_uptualize_me2.asp:

<!--#include file="../../bd/conn.asp"-->
<%
status = Replace(Trim(Request("status")),"'","")
sql = "update "&bd_&".atualize_me set status="&status&" where id=1;"
conn.execute(sql)
%>

Not HTML include the call to the script:

<script type="text/javascript"  src="js/arquivo.js"></script>

Let's say that the Site or system is already in production / Online and there are many clients accessing, just update the status = 1 field in the update_me table, ready the file itself will make this request 1 time and if necessary zera the browser cache. Note: tested on Chrome and Firefox = ok

 0
Author: Wilson Rosa Gomes, 2017-01-22 22:13:43