Jef Claes

On software and life

09 Jun 2013

Angular.js and IE8 caching

Older Internet Explorer versions are notorious for agressively caching AJAX requests. In this post, you’ll find two techniques that combat this behaviour.

The first option is to have your server explicitly set the caching headers.

Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
Response.Cache.SetValidUntilExpires(false);
Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();

Since you don’t necessarily own the server, or clients might already have cached some requests, you can trick the browser into thinking each request is a fresh one by making each url unique. Our old pal jQuery already learned this trick years ago. Angular.js on the other hand seems to have forgotten. We can get around though.

If you merge this pull request (or wait for angular.js version 1.2), you will find angular’s HTTP provider augmented with request interceptors, enabling you to mold the request before it goes out.

The interceptor we’re adding to kill the cache only touches GET requests, appending a ‘cacheSlayer’ querystring parameter with a timestamp to each url, making it unique and thus bypassing the cache. A factory is responsible for creating it, while a config block pushes it into a collection of interceptors.

var AppInfrastructure = angular.module('App.Infrastructure', []);

AppInfrastructure
    .config(function ($httpProvider) {
        $httpProvider.requestInterceptors.push('httpRequestInterceptorCacheBuster');
    })    
    .factory('httpRequestInterceptorCacheBuster', function () {
        return function (promise) {
            return promise.then(function (request) {
                if (request.method === 'GET') {
                    var sep = request.url.indexOf('?') === -1 ? '?' : '&';
                    request.url = request.url + sep + 'cacheSlayer=' + new Date().getTime();
                }

                return request;
            });
        };
    });    

I hope this helps someone spending time on more important matters.