Monday, September 26, 2011

Status Code 204 Bug in older jQuery

Recently debugging an old tool written partially in jQuery ( version 1.3.2 ), and found out that the ajax call always ends up going to the error() callback.  But when I ping the web service, it is returning 2XX which is totally fine.  And I kept tracing until I found out a bug in that version of jQuery, aha!

Hope this post help those who may have a chance maintaining tools that are developed using older version of jQuery.

Some blogs mentioned that it is the jQuery doesn't accept 204 as success. But when I traced the jQuery code, I saw that it actually accepts 204 as a success.  So "204" is not the main reason.  Look at the following code snippets :-

        httpSuccess: function( xhr ) {
                try {
                        return !xhr.status && location.protocol == "file:" ||
                                ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
                } catch(e){}
                return false;

The main reason is not the http code 204 itself, but it is about what 204 actually means.  HTTP 204 means No Content.  It seems like "No Content" is something not correct at the very first impression, but think about this way, what about people who wants a web service to response a success but they don't need a body or message (well, they just want to know it is a success and that's all).  And that is what HTTP 204 means, success but no content.   

Even though the above jQuery snippets says that 204 is a valid response, and treated it as success;  however, somewhere later, jQuery has this function to throw a "parseerror" when there is no content.

        httpData: function( xhr, type, s ) {
                var ct = xhr.getResponseHeader("content-type"),
                        xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
                        data = xml ? xhr.responseXML : xhr.responseText;

                if ( xml && data.documentElement.tagName == "parsererror" )
                        throw "parsererror";
                . . .

So this is what jQuery ( older version ) says, "We accept 204, but if it is no content, we will throw you an error".

In order to fix the issue, you will need to do something in your error() callback

error: function(xhr, errText) {
   if(xhr.status == 204) {
       _successHandler(what, ever);
   _errorHandler(what, ever);

No comments:

Post a Comment