It turns out, for reasons best known to itself, Internet Explorer will aggressively cache GET requests when using the XMLHttpRequest object. When writing an AJAX application this is particularly painful if you want your result to be dynamic.
If you can modify the server, the best approach is to ensure that the server correctly sets the
Cache-Control: no-cache
header, but this is not always possible if you are working with a legacy backend.Another solution is to use an HTTP POST instead, but again that's a problem if you working with existing code, or you are writing to a REST API and you want to keep the GET = Read and POST = Create idiom.
If you want to force the client to get it right this narrows your choices.
A commonly suggested approach is to generate a random request parameter and add this to your request either by appending
?requestId=r4nd0m-v4lu3
to the URI, or if your request already includes parameters appending &requestId=r4nd0m-v4lu3
. While this means you won't see the cached responses, the browser still does put these items in the cache, and if you are doing a large number of these requests, this will start to evict things that you actually want to be in there! It may also be a problem if your application enforces strict checking of the passed in parameters.The best approach I have found is to use the
If-Modified-Since
header with the date set to the Epoch (1970-01-01 00:00:00 GMT). The browser will not cache the result, and you will not have to worry about clashing with existing parameters. The nice thing about this approach is it is a general solution which you can put in a library and then not worry about problems with the backend.To do this when using the Google Web Toolkit (GWT) RequestBuilder interface it is simply a matter of using the setHeader method as follows:
void nonCachingHttpGet(String uri, String data, RequestCallback callback) RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, uri); // This header is required to force Internet Explorer to not cache values from // the GET response. builder.setHeader("If-Modified-Since", "01 Jan 1970 00:00:00 GMT"); builder.setHeader("Content-type", "application/x-www-form-urlencoded"); builder.setCallback(callback); builder.send(); }
5 comments:
Hey Dean. Nice blog. I've been meaning to do something myself for a while.
The java duck-typing really interesting while at the same time a crime against all things good ;-)
... but I'm interested in what you are up to with GWT ?
Hi Trevor, nice to hear from you!
See http://www.quest.com/authentication-services/Authentication-Services-4-Preview.aspx
In particular the part that says "Web based Administration Console". This is a full-blown application written in GWT with a J2EE backend.
Actually here is a much more helpful link with a free download: http://www.quest.com/FreeUnixIAM/
Thank you kindly for your post. Was having the same issue and now I'm back on the saddle again :)
Thank you very much, had similar problem and this fixed it. :)
Post a Comment