In this post, we will explore how to prevent caching get requests in Angular. This is an old issue that gets me every time I begin working on a new Angular project. Internet Explorer caches all GET requests, which means that a user won’t see any changes after a database update.
Table of contents
Solution #1: Use POST requests
The simplest way to prevent caching is to use POST
requests, since Internet Explorer only caches GET
requests.
Although it works, you can’t possibly use POST for everything following REST principles.
Solution #2: Add response headers in Angular
A better way to prevent caching GET
requests is to set necessary HTTP headers in Angular.
You need to specifically set the following headers to prevent caching:
"Cache-Control": "no-cache"
"Pragma": "no-cache"
"Expires": "Sat, 01 Jan 2000 00:00:00 GMT"
Code language: HTTP (http)
These headers must be set on every GET
request sent to the server.
An ideal way to implement this is to use an HttpInterceptor, which would allow us to intercept every HTTP request and set the headers above. The following CacheInterceptor
is an implementation is what I use, just put it in a typescript file.
import { HttpEvent, HttpHandler, HttpHeaders, HttpInterceptor, HttpRequest } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable()
export class CacheInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent> {
if (req.method === "GET") {
const httpRequest = req.clone({
headers: new HttpHeaders({
"Cache-Control": "no-cache",
"Pragma": "no-cache",
"Expires": "Sat, 01 Jan 2000 00:00:00 GMT"
})
});
return next.handle(httpRequest);
}
return next.handle(req);
}
}
Code language: TypeScript (typescript)
You may have noticed the if block for checking for request method. Essentially, we want to limit adding headers to GET
requests because Internet Explorer does not cache POST
requests.
With the custom interceptor in place, we need to hook it to the root component of the Angular app. It is most likely that the root module is called app.module.ts
.
Go ahead and add the following in the providers
array to begin using the CacheInterceptor
.
..
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: CacheInterceptor,
multi: true
}
...
Code language: TypeScript (typescript)
multi
option allows you to specify multiple interceptors, executing in the order specified in the providers array. You can set this to false, if you don’t have another interceptor
Solution #3: Disable response cache on the API
Yet another way to prevent Internet Explorer from caching GET
responses is to disable response cache in the API.
This ensures that the server will always serve fresh response to all clients. If you have multiple Angular clients using the same API, this may be the best solution as there is no need to update Angular code.
[HttpGet]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> Get(int id)
{
// Get record by id...
}
Code language: C# (cs)
Solution #4: Stop supporting IE ?
You have been looking for an excuse to do this so here you go: Microsoft urges you to stop using Internet Explorer.
This is easier said than done, like for example if you’re working on an internal app for the finance services industry.
Final thoughts
In this post, I explained how to prevent caching responses of GET requests in Angular when using Internet Explorer. There are valid reasons for caching, for example, a high traffic application which retrieves your user name on each page. Your name doesn’t change that often so it makes sense to cache the response.
Your specific requirements will dictate what solution you need to use as there is no one solution that fits all.
Like!! I blog frequently and I really thank you for your content. The article has truly peaked my interest.
This line has errors stating that both HttpRequest and HttpEvent require one argument. Can you provide thoughts?
intercept(req: HttpRequest, next: HttpHandler): Observable
Hi Nancy, thank you for your comment. Can you make sure you import and implement
HttpInterceptor
from"@angular/common/http"
please?