IE, jQuery, Rails, and HTTP, oh my!

Ben Scofield, Former Viget

Article Category: #Code

Posted on

We've been using jQuery more and more lately; thanks to the helpful jRails plugin, our transition from Prototype has been nearly seamless. Recently, however, I ran into a persistent problem with my $.ajax calls in IE -- namely, that GET requests were coming across as POSTs (to both Apache and my application), each of which generated a MethodNotAllowed error for the particular URL it was hitting. In Firefox and Safari, of course, the requests came through as the GETs they were supposed to be. After a long search and several false leads, I finally discovered that the culprit was the following bit at the bottom of our application.js:

$(document).ajaxSend(function(event, request, settings) { if (typeof(AUTH_TOKEN) == "undefined") return; // settings.data is a serialized string like "foo=bar&baz=boink" (or null) settings.data = settings.data || ""; settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN); }); 

We use this code to handle Rails's built-in CSRF protection (as detailed here), but it turns out that in IE, adding to settings.data in this manner automatically turns your request into a POST, no matter what else you might specify. Once we found this, it was a simple matter to fix it; since CSRF protection (and the authenticity token) aren't needed for GET requests, we can exit out of the function before any harm is done in those cases:

$(document).ajaxSend(function(event, request, settings) { if (settings.type == 'GET' || settings.type == 'get' || typeof(AUTH_TOKEN) == "undefined") return; // settings.data is a serialized string like "foo=bar&baz=boink" (or null) settings.data = settings.data || ""; settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN); }); 

And like magic, everything just works in IE as it should.

Related Articles