Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

stop caching views in Angular.js

for some reason all of my html seems to be 100% cached in chrome.

I am using angular 1.2 with .net web api 2 project, and my content is served in index.html.

I did not make any cache policy changes yet, but it seems to be caching everything very heavily.

none of the changes i make (to the views) are reflected until i clear browser cache.

I don't see new changes after pressing f5 or after publishing my site to the server and doing f5 on that. I have to either explicitly clear browser cache, or keep console open with "no caching while dev tools are open" setting on.

I want to prevent asking users to clear their browser cache when new versions are deployed.

like image 542
Sonic Soul Avatar asked Mar 04 '14 22:03

Sonic Soul


1 Answers

Since noone is chiming in, i'll post the solution I implemented, which works, but could be better

IIS:

http features > http response headers > set custom headers > Expire Web Content: Immediately
(if you don't see http features, you'll have to add the feature to your iis server)

index.html:

<meta http-equiv="CACHE-CONTROL" content="NO-CACHE">
<meta http-equiv="CACHE-CONTROL" content="NO-STORE"> 
(these may cause issues in older versions of IE)

this works, but I'd prefer to strike a better balance of caching between releases.

Alternative approach would be to use a build tool such as Grunt, and generate unique filenames for your scripts in production and update links in index.html. This would be the best approach I believe, because full caching would be enabled, and browser would always make the request for new version of files since the names would be unique. (I've also seen people append ?v=666 to files, but from what i've read this is not a reliable approach)

Also if you're serving content from .Net pages (instead of basic .html) you have an option of using Bundler which does manage tags between releases.

bundles.Add(new ScriptBundle("~/bundles/angular").Include("~/Scripts/angular/angular.js")
                                                 .Include("~/Scripts/angular/angular-route.js"));

this will result in

<script src="/bundles/angular?v=20LMOimhsS0zmHdsbxeBlJ05XNyVXwPaS4nt3KuzemE1"></script>

update

additionally I've also been adding a version parameter in template includes. This prevents caching, but it may prevent caching completely so do some testing if you go that route

<div data-ng-include=" 'app/import/import-summary.html?v=' + appVersion "></div>

appVersion can be a global variable set in app.js

app.run(['$route', '$rootScope', function ($route, $rootScope) {
    $rootScope.appVersion = getBuildVersion(); // this can be read from assembly file version or any other place where versions are generated by your build server
}]); 
like image 194
Sonic Soul Avatar answered Sep 22 '22 15:09

Sonic Soul