Prevent IE from aggressively caching API responses

1 minute read

This was not an issue in Google Chrome but IE10’s caching of API responses was pretty aggressive. I was displaying some data to the users after a GET request and letting them make some changes. After sending the changes to the backend, I was making a GET request again to fetch the latest data but IE10 would show the cached data from the first GET request. It took a while to figure out what the issue but after that the fix was straightforward - set a Cache-Control: no-cache header on each request.

UDPATE

For Angular 4.3+, when using HttpClient, setting the header on each request can be achieved using Interceptors.

Here’s an interceptor that intercepts each http request and adds three headers.

// src/app/http-interceptors/no-cache-interceptor.ts
import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';

import { Observable } from 'rxjs';

/** Pass untouched request through to the next request handler. */
@Injectable()
export class NoCacheInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler):
    Observable<HttpEvent<any>> {
      req = req.clone({
        setHeaders: {
          'Cache-Control': 'no-cache',
          'Pragma': 'no-cache',
          'Expires': 'Sat, 01 Jan 2000 00:00:00 GMT'
        }
      });
      return next.handle(req);
  }
}

This is then used by adding the below code to app.module.ts. To use multiple interceptors, simple add them both as shown below while setting multi: true.

import { NoCacheInterceptor } from './http-interceptors/no-cache-interceptor';
...

@NgModule({
  declarations: [
    AppComponent,
    ...
    ],
  imports: [
    BrowserModule,
    HttpModule,
    ...
  ],
  entryComponents: [...],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: WinAuthInterceptor,
      multi: true
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: NoCacheInterceptor,
      multi: true
    },
    RequestService,
    ...
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

Old code

In request.service.ts

// To prevent IE from aggressively caching API responses
@Injectable()
export class NoCacheRequestOptions extends BaseRequestOptions {
    headers = new Headers({
        'Cache-Control': 'no-cache',
        'Pragma': 'no-cache',
        'Expires': 'Sat, 01 Jan 2000 00:00:00 GMT'
    });
}

In app.module.ts

import { NoCacheRequestOptions, RequestService } from './request.service';

...

@NgModule({
  declarations: [
    AppComponent,
    ...
    ],
  imports: [
    BrowserModule,
    HttpModule,
    ...
  ],
  entryComponents: [...],
  providers: [
      RequestService,
      { provide: RequestOptions, useClass: NoCacheRequestOptions }
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

Leave a Comment