IE9: Cache-Busting with Grape Middleware

Back | grape, rails, ruby | 9/14/2011 |

Ran into a series of weird bugs with IE9. Turned out that a lot of our API requests were cached on the client. I am not sure whether this is some clever plot to make things look crappy in IE work faster, but it was rather puzzling. Nothing in our API headers indicated that the data can be cached for any duration, but nothing indicated otherwise either. Generally I’d like IE to work more like other browsers these days, not the other way around.

It was pretty easy to add a set of no-cache headers with Grape Middleware.

  1. class ApiCacheBuster < Grape::Middleware::Base
  2.  
  3.   def after
  4.     @app_response[1]["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
  5.     @app_response[1]["Pragma"] = "no-cache"
  6.     @app_response[1]["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
  7.     @app_response
  8.   end
  9.  
  10. end

  1. class Api < Grape::API
  2.   use ApiCacheBuster
  3.   ...
  4. end

And, trying to get muscle memory for good habits, a test.

  1. require 'spec_helper'
  2.  
  3. describe ApiCacheBuster do
  4.   it "sets cache headers" do
  5.     get "/api/v1/ping"
  6.     response.body.should == "pong".to_json
  7.     response.headers["Cache-Control"].should == "no-cache, no-store, max-age=0, must-revalidate"
  8.     response.headers["Pragma"].should == "no-cache"
  9.     response.headers["Expires"].should == "Fri, 01 Jan 1990 00:00:00 GMT"
  10.   end
  11. end

The headers are inspired from this StackOverflow article, which shows how to do it with plain Rails controllers.