What changed in jQuery 1.9 to cause a $.ajax call to fail with syntax error

Gene Reddick picture Gene Reddick · Jan 22, 2013 · Viewed 12.3k times · Source

I'm making a REST DELETE call, which returns a 204. In jQuery 1.8.3 this works, and hits the request.done callback. But if I use 1.9 it goes to request.fail with a parsererror in the textStatus and a 'SyntaxError: Unexpected end of input' in the errorThrown.

remove = function (complete) {
            var self = this;
            var request = $.ajax({
              context: self,
              url: "/v1/item/" + itemId,
              dataType: "json",
              type: "DELETE"
            });
            request.done(removeCallback);
            request.fail(function (xhr, textStatus, errorThrown) {
                alert(errorThrown);
            });
            
        },

Anyone know what has changed in 1.9 that would cause this to fail, and what needs to change in order to fix it?

So, answering my own question it looks like this is in fact the problem:

From the jQuery upgrade guide

jQuery.ajax returning a JSON result of an empty string

Prior to 1.9, an ajax call that expected a return data type of JSON or JSONP would consider a return value of an empty string to be a success case, but return a null to the success handler or promise. As of 1.9, an empty string returned for JSON data is considered to be malformed JSON (because it is); this will now throw an error. Use the error handler to catch such cases.

So, if remove the dataType

dataType: "json",

It works in jQuery 1.8.3 and 1.9.

Answer

Noel Abrahams picture Noel Abrahams · Jan 25, 2013

An HTTP 204 response is not an empty string: it means there is no data. This is a valid response for delete and update operations.

This looks like a bug introduced in JQuery 1.9.

The reason removing the dataType property fixes this is because when it's set to "json" JQuery attempts to parse the content using JSON.parse and failing as a result. From the ticket:

This won't fail with any other dataType than "json" because the regression is due to the re-alignment of parseJSON with native JSON.parse (throwing an exception for null/undefined values).

Don't try the workaround suggested in the ticket of adding a handler for the 204 via the statusCode property, because both that handler and the error handler will be triggered. A possible solution is the following:

    $.ajax(url, {
    type: "DELETE",
    dataType: "json",
    error: function (error) {
        if (error.status === 204) {
            // Success stuff
        }
        else {
            // fail
        }
    }});