JSONP request error handling

Adrian Mojica picture Adrian Mojica · Sep 26, 2013 · Viewed 51.1k times · Source

I'm making an ajax jsonp request, but the failure error handling wont work. If the request is 404 or 500 it won't handle the error.

I've been looking around to find an answer to this, but can't find anything. There seems to be a solution with http://code.google.com/p/jquery-jsonp/, but I can't find any examples on how to use it.

function authenticate(user, pass) {       
    $.ajax ({
        type: "POST",
        url: "url",
        dataType: 'jsonp',
        async: false,
        //json object to sent to the authentication url
        data: {"u": userid, "p": pass},

        success: function (data) {
            //successful authentication here
            console.log(data);
        },
        error: function(XHR, textStatus, errorThrown) {
            alert("error: " + textStatus);
            alert("error: " + errorThrown);
        }
    })
}

Answer

jwaliszko picture jwaliszko · Sep 30, 2013

If you check jQuery.ajax() documentation, you can find:

error

A function to be called if the request fails (...) Note: This handler is not called for cross-domain script and cross-domain JSONP requests. This is an Ajax Event.

Because of that, you're forced to find workaround. You can specify timeout to trigger an error callback. It means that within specified time frame the request should be successfully completed. Otherwise, assume it has failed:

$.ajax({
    ...
    timeout: 5000, // a lot of time for the request to be successfully completed
    ...
    error: function(x, t, m) {
        if(t==="timeout") {
            // something went wrong (handle it)
        }
    }

});

Other issues in your code...

While JSONP (look here and here) can be used to overcome origin policy restriction, you can't POST using JSONP (see CORS instead) because it just doesn't work that way - it creates a element to fetch data, which has to be done via GET request. JSONP solution doesn't use XmlHttpRequest object, so it is not an AJAX request in the standard way of understanding, but the content is still accessed dynamically - no difference for the end user.

$.ajax({
    url: url,
    type: "GET"
    dataType: "jsonp",
    ...

Second, you provide data incorrectly. You're pushing javascript object (created using object literals) onto the wire instead of its serialized JSON representation. Create JSON string (not manually, use e.g. JSON.stringify converter):

$.ajax({
    ...
    data: JSON.stringify({u: userid, p: pass}),
    ...

Last issue, you've set async to false, while documentation says:

Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation.