Force javascript file update without disabling cache

16

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

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

Is there a standard or solution that forces the reload of JavaScript every time it changes, 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.

    
asked by anonymous 10.06.2015 / 02:49

4 answers

9

Hello.

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

In PHP it 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 web server header settings.

Update

The above solution can cause two problems:

1) The increase of internet traffic of the web server. 2) The web application loads slower 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 the CSS and JS files change version.

In ASP.NET:

I put a constant in the Web.config that indicates the version:

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

In Site.Master I 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 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>

Both 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 already itself by changing the "1254" numbering only when the CSS and JS files change version.

This last solution I consider to be the easiest.

References: Prevent Your CSS and JavaScript Files From Being Cached

    
11.06.2015 / 02:28
3

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

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

In it you configure the groups of scripts or styles that will be published on the pages.

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 Views , consumes by 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>
    
22.06.2016 / 15:43
1

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

Final result:

    <script src="script.js?"<?php echo filemtime("script.js"); ?>></script>
    
22.06.2016 / 15:21
0

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)

Place in the main file (in my case .js file) 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 */ }
        });
});

Page content json_atualize_me.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_atualize_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)
%>

In 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 customers accessing, just update the field status = 1 in the table update_me, ready the file itself will make this request 1 time and if necessary clear the browser cache . Note: Tested on Chrome and Firefox = ok

    
22.01.2017 / 23:13