How to append timestamp to the javascript file in ` – AJ Zane Apr 07 '14 at 20:12

  • 1
    I prefer the method proposed by AJ Zane because now you know exactly at what location your javascript file is included: at the location where the document write is located. – Serge van den Oever Apr 23 '14 at 21:07
  • could you please tell me how do i add this for large number of js and css files .. – Orange Nov 10 '15 at 14:46
  • @Gaurav You can do an array and append the file or use something like RequireJS - I suggest you make another question and post the link here and I will try to answer – TheBlackBenzKid Nov 11 '15 at 05:23
  • @TheBlackBenzKid [link](http://stackoverflow.com/questions/33632901/prevent-javascript-cacehing-by-appending-timestamp-or-version) – Orange Nov 11 '15 at 12:42
  • 1
    Heads up on document.write(): https://developers.google.com/web/updates/2016/08/removing-document-write – eflat Dec 01 '17 at 22:06
  • 14

    If you choose to use dates or a random numbers to append to your URI, you will provide opportunities for the end user to be served the same cached file and may potentially expose unintended security risks. An explicit versioning system would not. Here's why:

    Why "Random" and Random Numbers are both BAD

    For random numbers, you have no guarantee that same random number hasn't been generated and served to that user before. The likelihood of generating the same string is greater with smaller "random" number sets, or poor algorithms that provide the same results more often than others. In general, if you are relying on the JavaScript random method, keep in mind it's pseudo-random, and could have security implications as well if you are trying to rely on uniqueness for say a patch in one of your scripts for XSS vulnerabilities or something similar. We don't want Johnny to get served the old cached and unpatched JS file with an AJAX call to a no-longer trusted 3rd-party script the day Mr. Hacker happened to be visiting.

    Why dates or timestamps are bad too, but not as bad

    Regarding Dates as "unique" identifiers, JavaScript would be generating the Date object from the client's end. Depending on the date format, your chances for unintended caching may vary. Date alone (20160101) allows a full day's worth of potential caching issues because a visit in the morning results in foo.js?date=20160101, and so does a visit in the evening. Instead, if you specify down to the second (20160101000000) your odds of an end user calling the same GET parameter go down, but still exist.

    A few rare but possible exceptions:

    • Clocks get reset (fall behind) once a year in most time zones

    • Computers that reset their local time on reboot for one reason or another

    • Automatic network time syncing causing your clock to adjust backwards a few seconds/minutes whenever your local time is off from the server time

    • Adjusting time zones settings when traveling (The astronauts on the IIS travel through a zone every few minutes...let's not degrade their browsing experience :P)

    • The user likes resetting their system clock to mess with you

    Why incremental or unique versioning is good :)

    For a fontend only solution, my suggestion would be to set an explicit version, which could be simply hard-coded by you or your team members every time you change the file. Manually doing exactly as you had done in your same code of your question would be a good practice.

    You or your team should be the only ones editing your JS files, so the key take away isn't that your file needs to be served fresh every time, I just needs to be served fresh when it changes. Browser caching isn't a bad thing in your case, but you do need to tell the end user WHEN it should update. Essentially, when your file is updated, you want to ensure the client gets the updated copy. With this, you also have the added bonus of being able to revert to previous versions of your code without worry of client caching issues. The only drawback is you need to use due diligence to make sure you actually update the version number when you update your JS files. Keep in mind just because something isn't automated, doesn't mean it is necessarily bad practice or poor form. Make your solution work for your situation and the resources you have available.

    I suggest using a form like Semantic Versioning's rules to easily identify backwards or breaking compatibility by looking at the file name (assuming nobody in the development process fudged up their version numbering) if possible. Unless you have an odd use case, there is no good reason to force a fresh copy down to the client every time.

    Automated version incrementing on the client side with Local Storage

    If what you were after was frontend way to automate the generation of a unique version number for you so you don't have to explicitly set it, then you would have to implement some sort of local storage method to keep track of, and auto increment your file versions. The solution I've shown below would lose the ability for Semantic versioning, and also has the potential to be reset if the user knows how to clear Local Storage. However, considering your options are limited to client-side only solutions, this may be your best bet:

    <script type="text/javascript">
    (function(){
        /**
         * Increment and return the local storage version for a given JavaScript file by name
         * @param  {string} scriptName  Name of JavaScript file to be versioned (including .js file extension)
         * @return {integer}            New incremented version number of file to pass to .js GET parameter
         */
        var incrementScriptVer = function(scriptName){
    
            var version = parseInt(localStorage.getItem(scriptName));
    
            // Simple validation that our item is an integer
            if(version > 0){
                version += 1;
            } else {
                // Default to 1
                version = 1;
            }
    
            localStorage.setItem(scriptName, version);
    
            return version;
        };
    
        // Set your scripts that you want to be versioned here
        var scripts = ['foo.js', 'bar.js', 'baz.js'];
    
        // Loop through each script name and append our new version number
        scripts.map(function(script){
            var currentScriptVer = incrementScriptVer(script);
            document.write("<script language='text/javascript' type='text/javascript' src='http://yoursite.com/path/to/js/" + script + "?version=" + currentScriptVer + " '><\/script>");
        });
    })();
    
    </script>
    

    I'm going to mention for completeness, if you are converting from an old system of generating "random" numbered or dated GET variables, to an incrementing versioned system, be sure that you will not step over any potentially randomly generated files names with your new versioning system. If in doubt, add a prefix to your GET variable when changing methods, or simply add a new GET variable all together. Example: "foo.js?version=my_prefix_121216" or "foo.js?version=121216&version_system=incremental"

    Automated versioning via AJAX calls and other methods (if backend development is a possiblity)

    Personally, I like to stay away from local storage options. If the option is available, it would be the "best" solution. Try to get a backend developer make an endpoint to track JS file versions, you could always use the response to that endpoint determine your version number. If you are already using version control like Git, you could optionally have on of your Dev Ops team bind your versioning to your commit versions for some pretty sweet integration as well.

    A jQuery solution to a RESTful GET endpoint might look like:

    var script = "foo.js";
    
    // Pretend this endpoint returns a valid JSON object with something like { "version": "1.12.20" }
    $.ajax({
      url: "//yoursite.com/path/to/your/file/version/endpoint/" + script
    }).done(function(data) {
        var currentScriptVer = data.version;
        document.write("<script language='text/javascript' type='text/javascript' src='http://yoursite.com/path/to/js/" + script + "?version=" + currentScriptVer + " '><\/script>");
    });
    
    LWurm
    • 522
    • 6
    • 15
    11

    Insert the script dynamically via document.createElement('script'), then when you set the URL, you can use new Date().getTime() to append the extra parameter.

    If you are worried about your javascript executing before the script is loaded, you can use the onload callback of the script element (note that there are a few hoops to jump for IE though)

    epoch
    • 16,396
    • 4
    • 43
    • 71
    • Sorry, math random will add a point to the source, and unescaped this will lead to errors. Besides that, its returning a float and has some probability of repetition (that means it is possible That the user reloads an old script. – Beat Richartz Jul 13 '12 at 09:45
    • it does not matter if it is appended after the `?`, it can also easily be multiplied by a large number, but alas the Date option is better – epoch Jul 13 '12 at 09:46
    6

    If you can't user server side code then you can use getScript method to do the same.

    $(document).ready(function(){
      var randomNum = Math.ceil(Math.random() * 999999);
      var jsfile = 'scripts/yourfile.js?v=' + randomNum;
      $.getScript(jsfile, function(data, textStatus, jqxhr) { });
    });
    

    Reference URL: http://api.jquery.com/jQuery.getScript/

    (Please don't forget to mark as answer.)

    Jitendra Pancholi
    • 7,897
    • 12
    • 51
    • 84
    4

    Load scripts manually or with jQuery http://api.jquery.com/jQuery.getScript/. It also provides option to prevent chaching

    Madman
    • 3,171
    • 2
    • 32
    • 44
    4

    You can replace the source of the script doing this with pure Javascript

    // get first script
    var script = document.getElementsByTagName('script')[0]
    var new = document.createElement("script");
    // add the source with a timestamp
    new.src = 'yoursource.js?' + new Date.getTime().toString();
    new.type = 'text/javascript'
    script.parentNode.insertBefore(new,script);
    
    Beat Richartz
    • 9,474
    • 1
    • 33
    • 50
    • 1
      I doubt there is a problem here; because by the time you execute this, lets say in document.ready, page would have already loaded the javascript files specified in the script tag. so changing the source after the files are downloaded is of no use.. am i right? – Seeker Jul 13 '12 at 09:58
    • Right, I misunderstood the question a bit and my code also didn't work. Corrected it, Orwellian style. I will go to sleep now :) – Beat Richartz Jul 13 '12 at 10:11
    • 1
      still missing () on new Date.getTime().toString(); – cthiebaud Sep 01 '15 at 20:16
    1

    Replace regular expression if not alphanumeric Date.prototype.toISOString()

    var today = new Date();
    "MyFile_" + today.toISOString().replace(/[^\w]/g, "") + ".pdf"
    

    MyFile_20191021T173426146Z.pdf

    Gregory Bologna
    • 270
    • 1
    • 6
    • 20
    -2

    Old post but here is a one liner:

    <script src="../Scripts/source/yourjsname.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>
    
    rs1
    • 82
    • 2
    • 6