All the ajax calls that are sent from the IE are cached by Angular and I get a 304 response for all the subsequent calls. Although the request is the same, the response is not going be the same in my case. I want to disable this cache. I tried adding the cache attribute to $http.get but still it didn't help. How can this issue be resolved?
16 Answers
Instead of disabling caching for each single GET-request, I disable it globally in the $httpProvider:
myModule.config(['$httpProvider', function($httpProvider) { //initialize get if not there if (!$httpProvider.defaults.headers.get) { $httpProvider.defaults.headers.get = {}; } // Answer edited to include suggestions from comments // because previous version of code introduced browser-related errors //disable IE ajax request caching $httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT'; // extra $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache'; $httpProvider.defaults.headers.get['Pragma'] = 'no-cache'; }]); 20 Comments
If-Modified-Since header makes IIS+iisnode throw 400 Bad Request for every html file loaded through ngInclude and ngView. The following two headers fixed the issue for me though (I pulled them from Chrome, which didn't have the caching issue): $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache'; $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';You can either append a unique querystring (I believe this is what jQuery does with the cache: false option) to the request.
$http({ url: '...', params: { 'foobar': new Date().getTime() } }) A perhaps better solution is if you have access to the server, then you can make sure that necessary headers are set to prevent caching. If you're using ASP.NET MVC this answer might help.
1 Comment
$http.get(url+ "?"+new Date().toString()) is just another representation, without using parameter but adding it to query string.you may add an interceptor .
myModule.config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push('noCacheInterceptor'); }]).factory('noCacheInterceptor', function () { return { request: function (config) { console.log(config.method); console.log(config.url); if(config.method=='GET'){ var separator = config.url.indexOf('?') === -1 ? '?' : '&'; config.url = config.url+separator+'noCache=' + new Date().getTime(); } console.log(config.method); console.log(config.url); return config; } }; }); you should remove console.log lines after verifying.
4 Comments
$log in case you forget to take them out.I simply added three meta tags into index.html on angular project, and cache issue was solved on IE.
<meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache"> <meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT"> 1 Comment
index.html when we noticed IE11 was caching AJAX requests :/ But configuring $httpProvider as shown in other answers worked fine.Duplicating my answer in another thread.
For Angular 2 and newer, the easiest way to add no-cache headers by overriding RequestOptions:
import { Injectable } from '@angular/core'; import { BaseRequestOptions, Headers } from '@angular/http'; @Injectable() export class CustomRequestOptions extends BaseRequestOptions { headers = new Headers({ 'Cache-Control': 'no-cache', 'Pragma': 'no-cache', 'Expires': 'Sat, 01 Jan 2000 00:00:00 GMT' }); } And reference it in your module:
@NgModule({ ... providers: [ ... { provide: RequestOptions, useClass: CustomRequestOptions } ] }) 3 Comments
If-Modified-Since with some date far in the past using the above method.)headers: req.headers .set('Cache-Control', 'no-cache') .set('Pragma', 'no-cache') .set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')The guaranteed one that I had working was something along these lines:
myModule.config(['$httpProvider', function($httpProvider) { if (!$httpProvider.defaults.headers.common) { $httpProvider.defaults.headers.common = {}; } $httpProvider.defaults.headers.common["Cache-Control"] = "no-cache"; $httpProvider.defaults.headers.common.Pragma = "no-cache"; $httpProvider.defaults.headers.common["If-Modified-Since"] = "Mon, 26 Jul 1997 05:00:00 GMT"; }]); I had to merge 2 of the above solutions in order to guarantee the correct usage for all methods, but you can replace common with get or other method i.e. put, post, delete to make this work for different cases.
5 Comments
if (!$httpProvider.defaults.headers.get) { $httpProvider.defaults.headers.common = {}; }["If-Modified-Since"] = "0" is illegal and with generate a Bad Request on some back ends. it should be a date.This only line helped me (Angular 1.4.8):
$httpProvider.defaults.headers.common['Pragma'] = 'no-cache'; UPD: The problem is IE11 does aggressive caching. When I was looking into Fiddler I noticed that in F12 mode requests are sending "Pragma=no-cache" and endpoint is requested every time I visit a page. But in normal mode endpoint was requested only once at the first time when I visited the page.
1 Comment
I get it resolved appending datetime as an random number:
$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) { console.log('your get response is new!!!'); }); 1 Comment
Solution above will work (make the url unique by adding in the querystring a new param) but I prefer the solution propose [here]: Better Way to Prevent IE Cache in AngularJS?, which handle this at server level as it's not specific to IE. I mean, if that resource should not be cached, do it on the server (this as nothing to do with the browser used; it's intrisic to the resource).
For example in java with JAX-RS do it programatically for JAX-RS v1 or declativly for JAX-RS v2.
I'm sure anyone will figure out how to do it
2 Comments
also you can try in your servce to set headers like for example:
... import { Injectable } from "@angular/core"; import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http"; ... @Injectable() export class MyService { private headers: HttpHeaders; constructor(private http: HttpClient..) { this.headers = new HttpHeaders() .append("Content-Type", "application/json") .append("Accept", "application/json") .append("LanguageCulture", this.headersLanguage) .append("Cache-Control", "no-cache") .append("Pragma", "no-cache") } } .... Comments
The correct, server-side, solution: Better Way to Prevent IE Cache in AngularJS?
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")] public ActionResult Get() { // return your response } Comments
This issue is due to the IE caching problem as you said, you can test it in IE debug mode by pressing f12 (this will work fine in debug mode).IE will not take the server data in each time the page calls, it takes the data from cache. To disable this do either of the following:
- append the following with your http service request url
//Before (issued one)
this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" + engagementName , {})
//After (working fine)
this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" + engagementName + "?DateTime=" + new Date().getTime() + '', { cache: false })
- disable the cache for the entire Module :-
$httpProvider.defaults.headers.common['Pragma'] = 'no-cache';