10

Pretty straight-forward, I'm developing an MVC5 application and have noticed (lately) that my Browser appears to be caching the JavaScript code I have on the view within @section Scripts { }.

Currently I am developing with Chrome and I have tried CTRL+F5 & CTRL+SHFT+R which reloads the page, but the alert() I uncommented within the javascript code is still rendering as commented. I also tried going to my localhost through Incognito Mode as well as other Browsers (Firefox, IE) and am getting the same behavior. This is my /Home/Index.cshtml View, which is the default View which loads when the application starts. I have also tried adding some extra HTML text into the page and again the new code is not taking effect/showing.

My current Chrome version is Version 41.0.2272.118 m if anyone has any ideas what might be going on?


UPDATE:

I have gone under the Developer Tools => General Settings in Chrome and checked [X] Disable cache (while DevTools is open) and then repeatedly (with DevTools still open) tried CTRL+SHFT+R and CTRL+F5 with the same results of before where my changes are not taking effect.

UPDATE 2:

With DevTools open I have also held the Refresh button down and tried Normal/Hard/and Empty Cache & Hard Reload options all with the same result. For simplicity of testing I added an alert in the below to dispaly as soon as the page loads (and currently no alert comes up):

$(document).ready(function () {
            alert("Test");
            // Other Code/Functions -- No Error showing in Console
});
Analytic Lunatic
  • 3,619
  • 21
  • 65
  • 112
  • You can disable Chrome's cache when the Developer Tools is open: http://stackoverflow.com/a/7000899/1710624 – Mahmoud Ali Apr 08 '15 at 14:30
  • Can you post the contents of the view for us to see with the @section Scripts { } ?? Might be easier if we can see what you've done. Also with chrome open developer tools (F12) and click on the cog to open the settings, there is a 'Disable cache' checkbox, tick it and now if you refresh the page with developer tools open it won't use the cache – matt_lethargic Apr 08 '15 at 14:30
  • Also, this may not help, but when the chrome debug panel is open you can press and hold the page reload button for reload options. Choose empty cache and hard reload to also clear any subsequent section loads from the cache too. See http://stackoverflow.com/questions/14969315/whats-the-difference-between-normal-reload-hard-reload-and-empty-cache-a for more info. – Radio Apr 08 '15 at 14:35
  • Are you using Bundling/Minification from MVC or any other mechanisms that does any kind of transformation to your script files? – Mahmoud Ali Apr 08 '15 at 15:18
  • @MahmoudAli, Yes, I have some bundles setup with `BundleConfig.cs`, but this code in particular is rendered directly in `@section Scripts { }` on my View -- and now changes to the View code are not showing up either it seems. – Analytic Lunatic Apr 08 '15 at 15:37
  • @AnalyticLunatic I know this might seem obvious but, are you completely sure you are editing the same files you are accessing? Double check everything, I've lost many hours editing a file only to find out it wasn't the file or server I thought it was. – Mahmoud Ali Apr 08 '15 at 15:41
  • @AnalyticLunatic see my answer below, try using the `BundleTable.EnableOptimizations` and adding this script via Bundle, or running your code in Release mode. Open the developer tools and check the network tab to see if you are loading the optimized version. If you still get cache problems, then it might something else causing this, probably not related to browser caching. – Mahmoud Ali Apr 08 '15 at 15:46

3 Answers3

33

If you are using Bundling from MVC, you have two options to disable caching:

  1. Use BundleTable.EnableOptimizations. This instructs the bundling to minify and optimize your bundle even while debugging. It generates a hash in the process, based on the content of the script, so your customers browsers can cache this file for a long time. It will generate a whole different hash the next time your file changes, so your customers can see your changes. The downside is that your script will become unreadable and you won't be able to debug it, so this might not be your best option.
  2. Use System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("url", true) to resolve your script's URL, the second parameter (true) is requiring a hash to be generated with the URL, thus, preventing caching from your browser when you change the file. This is exactly the same hash generated in the first option, but without minifying.

I created a small demo showing that the second option prevents caching from happening, the trick is getting the hash generated from your script's content without minifying your script.

I created a script file called myscript.js with this content:

$(document).ready(function () {
    alert('a');
});

Then I added this to my BundleConfig.cs:

// PLEASE NOTE this is **NOT** a ScriptBundle
bundles.Add(new Bundle("~/bundles/myscripts").Include(
    "~/Scripts/myscript*"));

If you add a ScriptBundle, you will get a minified response again, since ScriptBundle is just a Bundle using JsMinify transformation (source). That's why we just use Bundle.

Now you can just add your script using this method to resolve the script URL with the hash appendend. You can use the Script.Render

@Scripts.Render(System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/myscripts", true))

Or the script tag:

<script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/myscripts", true)"></script>

Either way will generate a URL with a hash to prevent caching:

enter image description here

After editing my file:

enter image description here

Mahmoud Ali
  • 1,096
  • 1
  • 13
  • 26
  • 3
    Sometimes it is a total shame you couldn't upvote n^n times a reply... Great one! – Shockwaver Apr 08 '16 at 15:12
  • 1
    great answer, it works like a charm for me ! Thank you – Robouste Jan 18 '17 at 12:49
  • Nice one! Worked perfect. Thanks – CodeHacker Feb 06 '17 at 09:07
  • Does minification force to get latest javascript even if BundleTable.EnableOptimizations = false? Beause on DEV you dont have that to be true. Thanks – VAAA Aug 12 '17 at 22:00
  • It is not the minification itself that makes the latest JS file to be provided. It is the hash generated that does it. My solution does exactly that: forces a hash to be generated even while EnableOptimizations is set to false. – Mahmoud Ali Aug 14 '17 at 16:15
6

You might want to add a no_cache variable after your script url like:

<script src="js/stg/Stg.js?nocache=@random_number"></script> 

If you manage to put a random number to the place i indicated, the browser will automatically download the latest version of the script after an F5

szinter
  • 283
  • 1
  • 8
3

A quick trick that solves this problem consists of opening the script file in a new tab, then refresh it on this page. If you happen to have Chrome dev tools open it will even refresh it there.

From dev tool you can even easily right click-open in new tab the script.

Etienne
  • 1,010
  • 11
  • 21