I have a rest endpoint that returns a list on a GET call. I also have a POST endpoint to add new items and a DELETE to remove them. This works in Firefox and Chrome, and the POST and DELETE work in IE11. However, the GET in IE11 only works on initial load of the page. Refreshing returns cached data. I have seen post about this behavior in Angular 1 but nothing for Angular 2(release candidate 1).

- 10,157
- 3
- 61
- 54

- 2,852
- 2
- 24
- 34
-
4If your GET api does not specify Any Cache Control header -> It means the response is cacheable if the status is 200 OK. – LHA Jun 10 '16 at 19:31
-
3See also http://stackoverflow.com/questions/36500804/proper-way-to-prevent-angular2-http-request-caching-in-internet-explorer-ie for a client side workaround. – Günter Zöchbauer Jun 10 '16 at 19:34
-
@Loc I added the Cache-Control values no-store and no-cache and still get the same result in IE only. – cmaynard Jun 10 '16 at 20:01
-
1http://stackoverflow.com/questions/32261000/how-to-avoid-ajax-caching-in-internet-explorer-11-when-additional-query-string-p – Günter Zöchbauer Jun 11 '16 at 08:57
-
4Looks like I needed to specify more cache headers, I had `Cache-Control: not-store, no-cache` bu needed to add `Pragma: no-cache Expires: 0` – cmaynard Jun 13 '16 at 11:34
-
Do not forget, that your back-end should be configured to accept those headers. – Sargon Feb 03 '17 at 16:26
7 Answers
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'
});
}
Module:
@NgModule({
...
providers: [
...
{ provide: RequestOptions, useClass: CustomRequestOptions }
]
})

- 10,157
- 3
- 61
- 54
-
3That is a great solution for the making all requests from angular request no cache, however I don't want that behavior for all requests as some requests can be cached just fine. I went with setting the appropriate headers server side. I would rather the server have the caching smarts anyways. I may have worded the question poorly. – cmaynard Aug 31 '17 at 14:49
-
1@cmaynard I clashed into your question while looking on how to set up global caching for Andular, so from google perspective your wording is perfect for something people search look for :) – Vitaliy Ulantikov Sep 01 '17 at 06:57
-
This solution didn't work for me, I had to manually disable the cache by using http://docs.netapp.com/sgws-110/index.jsp?topic=%2Fcom.netapp.doc.sg-app-install%2FGUID-1E34D79A-2EB8-4A0D-AA47-E7BB62B8C77B.html – resolve_promise Nov 27 '18 at 12:44
-
1
-
@cmaynard I was thinking about this, perhaps and option is to only provide this httpinterceptor to your Rest services. – Joey Gough Jun 21 '19 at 11:16
Today, I also had this problem, (damn IE).
In my project, I use httpclient
, that hasn't BaseRequestOptions
.
We should use Http_Interceptor
to resolve it!
import { HttpHandler,
HttpProgressEvent,
HttpInterceptor,
HttpSentEvent,
HttpHeaderResponse,
HttpUserEvent,
HttpRequest,
HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
export class CustomHttpInterceptorService implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
const nextReq = req.clone({
headers: req.headers.set('Cache-Control', 'no-cache')
.set('Pragma', 'no-cache')
.set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
.set('If-Modified-Since', '0')
});
return next.handle(nextReq);
}
}
Module provide
@NgModule({
...
providers: [
...
{ provide: HTTP_INTERCEPTORS, useClass: CustomHttpInterceptorService, multi: true }
]
})
-
4Thanks, this is the correct answer for Angular 5. However since I specified Angular 2 in the original question I'll leave that answer marked correct for this question, have an upvote! – cmaynard Feb 27 '18 at 18:52
-
2If you use CORS you may need to add all of the headers (Cache-Control, Pragma etc.) to `Access-Control-Request-Headers` on the server side. Otherwise you run into CORS issues. Meaning your request will fail. – Arikael Jan 10 '19 at 07:52
Forward the stackoverflow response Angular IE Caching issue for $http, you should add the headers 'Pragma', 'no-cache', 'If-Modified-Since' to each 'GET' request.
The interceptor's scenario is not supported to angular 2 anymore. So you should extend the http as it is described here What is httpinterceptor equivalent in angular2?.
Angular 4.3 now includes the HttpClient service, which supports interceptors.

- 3,287
- 1
- 22
- 30

- 101
- 1
- 8
Edit: See comment below - this is not necessary (in the vast majority of cases).
Expanding on Jimmy Ho's answer above, I only want to prevent caching of my API calls, and not other static content which will benefit from being cached. All of my API calls are to URLs that contain "/api/", so I amended Jimmy Ho's code with a check that only adds the cache headers if the requested URL contains "/api/":
import { HttpHandler,
HttpProgressEvent,
HttpInterceptor,
HttpSentEvent,
HttpHeaderResponse,
HttpUserEvent,
HttpRequest,
HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
export class CustomHttpInterceptorService implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
// Only turn off caching for API calls to the server.
if (req.url.indexOf('/api/') >= 0) {
const nextReq = req.clone({
headers: req.headers.set('Cache-Control', 'no-cache')
.set('Pragma', 'no-cache')
.set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
.set('If-Modified-Since', '0')
});
return next.handle(nextReq);
} else {
// Pass the request through unchanged.
return next.handle(req);
}
}
}

- 1,110
- 11
- 21
-
2The HttpInterceptor only affects requests going through angular (so usually HttpClient in your angular services) which are API calls 99% of the time. So I don't think this additional check is necessary. Not unless you are requesting static content inside your service layer for some reason. – LambdaCruiser Jan 03 '19 at 13:53
-
@LambdaCruiser, yes, you're quite right. It's not really required. I'll leave this here just in case anybody falls into the same trap. – AndrWeisR Jan 04 '19 at 10:18
As answered above, you can use http request interceptor to modify or set a new header on the request. Below is a much simpler way of setting headers on http request interceptor for Later angular versions(Angular 4+). This approach would only set or update a certain request header. This is to avoid removing or overriding some important headers like the authorization header.
// cache-interceptor.service.ts
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
} from '@angular/common/http';
@Injectable()
export class CacheInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
const httpRequest = req.clone({
headers: req.headers
.set('Cache-Control', 'no-cache')
.set('Pragma', 'no-cache')
.set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
})
return next.handle(httpRequest)
}
}
// app.module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http'
import { CacheInterceptor } from './cache-interceptor.service';
// on providers
providers: [{ provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }]

- 157
- 3
- 6
Disable browser caching with meta HTML tags:-
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0">
<meta http-equiv="expires" content="0">
<meta http-equiv="pragma" content="no-cache">

- 3,748
- 4
- 35
- 70
A little late, but I ran into the same problem. For Angular 4.X I wrote a custom Http class to append a random number to the end to prevent caching by IE. It is based on the 2nd link by dimeros (What is httpinterceptor equivalent in angular2?). Warning: not guaranteed to be 100% bug free.
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Http, Response, XHRBackend, RequestOptions, RequestOptionsArgs,
URLSearchParams } from '@angular/http';
@Injectable()
export class NoCacheHttp extends Http {
constructor(backend: XHRBackend, options: RequestOptions) {
super(backend, options);
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
//make options object if none.
if (!options) {
options = { params: new URLSearchParams() };
}
//for each possible params type, append a random number to query to force no browser caching.
//if string
if (typeof options.params === 'string') {
let params = new URLSearchParams(options.params);
params.set("k", new Date().getTime().toString());
options.params = params;
//if URLSearchParams
} else if (options.params instanceof URLSearchParams) {
let params = <URLSearchParams>options.params;
params.set("k", new Date().getTime().toString());
//if plain object.
} else {
let params = options.params;
params["k"] = new Date().getTime().toString();
}
return super.get(url, options);
}
}

- 1
- 1

- 475
- 1
- 5
- 12
-
1I've used that technique in the past to 'fool' caching. I think it's useful, but it's usually better to set the appropriate headers instead. – cmaynard Aug 31 '17 at 14:51