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.

[toc]

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.

Umut Esen

Software Engineer specialising in full-stack web application development.

Leave a Reply

This Post Has 3 Comments

  1. ปั้มไลค์

    Like!! I blog frequently and I really thank you for your content. The article has truly peaked my interest.

  2. Nancy Sorensen

    This line has errors stating that both HttpRequest and HttpEvent require one argument. Can you provide thoughts?

    intercept(req: HttpRequest, next: HttpHandler): Observable

    1. Umut Esen

      Hi Nancy, thank you for your comment. Can you make sure you import and implement HttpInterceptor from "@angular/common/http" please?