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?
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';
}]);
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.
$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.
$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">
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 }
]
})
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.
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.
To avoid caching, one option is to give different URL for the same resource or data. To generate different URL, you can add a random query string to the end of the URL. This technique works for JQuery, Angular or other type ajax requests.
myURL = myURL +"?random="+new Date().getTime();
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!!!');
});
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
This is a little bit to old but: Solutions like is obsolete. Let the server handle the cache or not cache (in the response). The only way to guarantee no caching (thinking about new versions in production) is to change the js or css file with a version number. I do this with webpack.
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") } } ....
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
}
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';
meta http-equiv="Cache-Control" content="no-cache"
I just added this to View and it started working on IE. Confirmed to work on Angular 2.
An option is to use the simple approach of adding a Timestamp with each request no need to clear cache.
let c=new Date().getTime();
$http.get('url?d='+c)
Try this, it worked for me in a similar case:-
$http.get("your api url", {
headers: {
'If-Modified-Since': '0',
"Pragma": "no-cache",
"Expires": -1,
"Cache-Control": "no-cache, no-store, must-revalidate"
}
})
Success story sharing
If-Modified-Since
header makes IIS+iisnode throw 400 Bad Request for every html file loaded throughngInclude
andngView
. 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';
If-Modified-Since = "0"
header breaks Tomcat (Problem with parsing header date, as0
is not valid value RFC). Fixed using valueMon, 26 Jul 1997 05:00:00 GMT
instead.