WebDev: jQuery, JSON, IE and Caching

1 minute read

I’m almost ready to update the production version of UVFood.com. I’ve been testing against Firefox during development, but I can’t possibly deploy the update without testing against other browsers. Safari turned up no surprises, and Opera has turned up a weird little problem that doesn’t make any sense.

But of course it was Internet Explorer that had the biggest issues.

Bookmarking is done via Ajax. When you bookmark a listing the icon changes from a heart with a plus sign to a heart with a minus sign, the count of the number of times the the listing was bookmarked is updated and a message is displayed that confirms the item was bookmarked. This works fine with Safari, Firefox and Opera. Internet Explorer, however, exhibits some truly erratic behavior. When you bookmark a listing in IE everything you expect happens. But when you click again to remove it from the bookmarks - everything that happened the last time happened again.

Entering a review worked, though. But clicking stars to rate a listing had a similar problem.

The problem was that jQuery on IE was caching the JSON results, something it wasn’t doing on Safari or Firefox.

The first thing I tried was to make sure that my server returned a header in the response to tell the client not to cache the results. It’s a simple header line: Cache-Control: no-cache

Unfortunately this didn’t change anything. It’s still good practice to make sure that your server emits the correct cache control headers, though.

Then I remembered a discussion of jQuery and GET vs. POST methods. GET is meant to be idempotent, no ill effects if it’s repeated (a request to move to position 8 is idempotent; a request to move to the next position is not). And it may be okay to store the results of a GET. POST is meant to be used for other requests.

Unfortunately, the convenience function that jQuery offers for dealing with jSON Ajax requests is getJSON(), which uses a GET request. It’s easy to write a postJSON() convenience function, however. Just add this to your jQuery initialization code: $.postJSON = function(url, data, callback) { $.post(url, data, callback, "json");

Changing my code to use postJSON() instead of getJSON() solved the problem.