1

Possible Duplicate:
How do I force the refresh of javascript files in a browser?

My application in ASP.NET MVC based and javascript files are included in .csHtml file.

I require this so that the user do not have to do a [Ctrl+F5] or manually clear cache and the most recent version of javascript file is loaded everytime in the browser.

I appreciate if some examples can be provided.

Primary technique suggested is to use a dummy paramater while including the file. Also I do not what to change the parameter manually every time I modify a js file. Need some examples if this can be done automatically.

EDIT 1: Please provide solution to this with ASP.NET MVC prospective.

Community
  • 1
  • 1
Atur
  • 1,392
  • 6
  • 26
  • 37
  • I had already asked similar question at http://stackoverflow.com/questions/14524203/how-to-clear-browser-cache-and-history-via-javascript but it was closed before i could get complete answer. Primary technique suggested are to used hash etc as paramater while including the file. Need more help on how to do so. – Atur Jan 27 '13 at 04:02
  • Duplicate of [How do I force the refresh of javascript files in a browser?](http://stackoverflow.com/questions/8230589/how-do-i-force-the-refresh-of-javascript-files-in-a-browser) (and [this one](http://stackoverflow.com/questions/32414/how-can-i-force-clients-to-refresh-javascript-files) and others). – nnnnnn Jan 27 '13 at 04:04
  • @nnnnnn I do not what to change the parameter manually every time I modify a js file – Atur Jan 27 '13 at 04:06
  • If you use the query path technique (`something.js?randomParam=1234`) you don't change the parameter manually at all ever, you either do it automatically in your build process or you have a little server-side code to generate a random number. On the client side this makes the browser reload the JS file every time whether it's changed or not. – nnnnnn Jan 27 '13 at 04:07
  • What version of MVC are you using? The newest version by default includes Bundling (http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification) which will do what you are requiring, as in, it changes a parameter every time the files change. – MikeSmithDev Jan 27 '13 at 04:09
  • @nnnnnn I will try some code to generate this randomParam on client side ( in the base .csHtml file). – Atur Jan 27 '13 at 04:12
  • @atur check my answer. MVC provides this functionality. – MikeSmithDev Jan 27 '13 at 04:15
  • @MikeSmithdev I am using MVC3 – Atur Jan 27 '13 at 04:20
  • `scripts.js?ts={insert_file_timestamp_herE}` – Peter Jan 27 '13 at 09:33

4 Answers4

1

Put a version number in the filename for your JS files (like jQuery does). Then, whenever you rev the JS files, you bump the version and change the HTML files that include it.

The jQuery file naming example:

jquery-1.8.3.js
jquery-1.9.0.js

This lets you set very long caching on your server for the JS files themselves which really helps with performance on your site. But, any time you rev the JS files, the viewer gets the new JS files immediately because the newly named files are pulled by the new HTML file because they aren't in the browser cache.

jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • 1
    there a too many js files in my application and its not feasible to change the name of files every time. The application is still under development and daily changes are pretty common. – Atur Jan 27 '13 at 04:11
  • That is not THE best way for what he is trying to do. – MikeSmithDev Jan 27 '13 at 04:18
  • 1
    @MikeSmithDev - how else do you get long term caching of JS files and instantaneous updates when there are new versions? Your answer is just another method of a unique name - same general solution. Changing the name of the file is the only way to get both these advantages. – jfriend00 Jan 27 '13 at 04:19
  • In my opinion having the version number in the file name is the most reasonable option for third party JS includes. For your own scripts some kind of build/deployment tool versioning is better if available (as per Mike's suggestion). – nnnnnn Jan 27 '13 at 04:24
  • @nnnnnn - aren't you just talking about a tool that manages a unique filename/URL for you? The concept is the same, right? – jfriend00 Jan 27 '13 at 04:29
  • @jfriend00 see my updated answer it shows a little more about what I was referring to. – MikeSmithDev Jan 27 '13 at 04:53
  • @jfriend00 - Yes, you're right. I guess I was trying to say that when you provide a third-party library to others (like jQuery) you don't want new versions of the file to take effect automatically. – nnnnnn Jan 27 '13 at 05:09
0

You can do cache-busting by attaching a random hash or number URL parameter after each javascript file URL like so:

http://www.bestsiteonearth.yes/cool_javascript.js?cache_buster=2187sasas1289012890aohkjaiosa0990

Since that number is different each time the page is loaded the URL will not be cached. More info here. Tutorial gives PHP examples, but if you know how to create a hash or random number in any language & can attach it to a URL you are good to go.

Giacomo1968
  • 23,903
  • 10
  • 59
  • 92
  • If you're going to do this, then you might as well just configure the server to not allow browser caching (and lose all performance benefits of caching). – jfriend00 Jan 27 '13 at 04:07
  • Not true. If you only do it for the JavaScript files, the rest of the files can still be cached. Images, HTML, CSS & such. Doing this selectively is not unusual & the way online ad system avoid ads caching. – Giacomo1968 Jan 27 '13 at 04:08
  • Jake, I was talking about configuring the server to stop caching of JS files which solves the problem, but loses all performance advantages of JS caching. – jfriend00 Jan 27 '13 at 04:16
0

Personally I use PHP, but the way I do this is to search the output buffer for static files, such as images, scripts and stylesheets (and audio, video, whatever), then retrieve their modification time from the filesystem and append it as /t=TIMESTAMP. I then use .htaccess to strip the timestamp off and get the original filename. This is preferred over query strings because many clients will not cache files with query strings, and it's also preferred over versioning because it updates automatically simply by modifying the file.

Niet the Dark Absol
  • 301,028
  • 70
  • 427
  • 540
0

You want to use Bundling and Minification. Depending on your version of MVC, the implementation is slightly different. In the newest version, it is used by default.

Bundling and Minification will combine and minify all your scripts (and styles sheets) into one file (or multiple, depending on how you use it) and serve them up with a unique parameter. Any time a file changes in that particular bundle (and thus the user would require to download the new files) the parameter automatically changes.

For MVC3, you'll need to install Microsoft Web Optimization.

Then in your global.ascx, you'd do something like this and call it from Application_Start:

private static void SetupBundling()
{
     var jsBundle = new Bundle("~/Scripts/js", typeof(JsMinify));
     jsBundle.AddDirectory("~/Scripts/", "*.js", false);
     jsBundle.AddDirectory("~/Scripts/anothr-good-folder/", "*.js", false);
     BundleTable.Bundles.Add(jsBundle);

     var randomBundle = new Bundle("~/Scripts/random", typeof(JsMinify));
     randomBundle.AddFile("~/Scripts/random/main.js");
     randomBundle.AddFile("~/Scripts/random/cool.js");
     BundleTable.Bundles.Add(randomBundle);

     var cssBundle = new Bundle("~/Content/css", typeof(CssMinify));
     cssBundle.AddDirectory("~/Content/", "*.css", false);
     BundleTable.Bundles.Add(cssBundle);
}

So that first bundle will bundle every .js file in your ~/Scripts folder. In your head file you can reference it like:

<script src="@Microsoft.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")" type="text/javascript"></script>

And it will be rendered like:

<script src="/Scripts/js?v=-2573834892993289" type="text/javascript"></script>

And any time one of your .js files change (or .css), so will the parameter.

Similar implementation for the CSS bundle, and also if you want to reference the randomBundle only on certain pages.

MikeSmithDev
  • 15,236
  • 4
  • 54
  • 85
  • I am using MVC3 Bundling and Minification looks like a good approach. But I have one more point. Not all javascript files are loading at the start. They are loaded as required. Hence, I am not bundle them together. – Atur Jan 27 '13 at 04:25
  • @atur You can create as many bundles as you want and reference the bundles as needed. You can create bundles by files only, or by whole directories. – MikeSmithDev Jan 27 '13 at 04:32
  • so @MikeSmithDev even when I add/include javascript files at runtime will this approach work – Atur Jan 27 '13 at 04:40
  • @atur can you explain more what you mean by that? I'd probably be best to put all of your custom scripts into a bundle, and then reference that bundle as needed. By the time they are combined and minified, the benefit of the user downloading that one file once will outweigh multiple smaller requests. – MikeSmithDev Jan 27 '13 at 04:45