JSONP request error handling
Asked Answered
I

5

40

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);
        }
    })
}
Impecunious answered 26/9, 2013 at 18:9 Comment(0)
E
39

Two ways to handle error,

  1. There is no error handling for cross domain JSONP requests. Use jsonp plug-in available on Github https://github.com/jaubourg/jquery-jsonp that provides support for error handling.

  2. jQuery ajax Timeout - Timeout after a reasonable amount of time to fire the error callback because it might have failed silently. You may not know what the actual error (or error status) was but at least you get to handle the error

Edelstein answered 6/10, 2013 at 10:34 Comment(1)
Method 2 is demostrated in the answer below: https://mcmap.net/q/395325/-jsonp-request-error-handlingLandward
R
53

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.

Recitativo answered 30/9, 2013 at 18:25 Comment(2)
Just want to add that the AJAX documentation that is linked to in the answer above also states under the timeout parameter: In Firefox 3.0+ only, script and JSONP requests cannot be cancelled by a timeout; the script will run even if it arrives after the timeout period.Galoshes
Tim McClure. What Tim Mclure said is true and I've been searching the internet for 2+ days now trying to find a solution on how to handle the "Uncaught TypeError: jQuery110203912213369484832883_193467225 is not a function". Try-catch is not capturing it. I wrapped my $.ajax call with it but no luck.Aeneous
E
39

Two ways to handle error,

  1. There is no error handling for cross domain JSONP requests. Use jsonp plug-in available on Github https://github.com/jaubourg/jquery-jsonp that provides support for error handling.

  2. jQuery ajax Timeout - Timeout after a reasonable amount of time to fire the error callback because it might have failed silently. You may not know what the actual error (or error status) was but at least you get to handle the error

Edelstein answered 6/10, 2013 at 10:34 Comment(1)
Method 2 is demostrated in the answer below: https://mcmap.net/q/395325/-jsonp-request-error-handlingLandward
P
11

I've been struggling like you for a while trying to handle errors on ajax jsonp DataType requests, however I want to share you my code, hope it helps. A basic thing is to include a timeout on the ajax request, otherwise it'll never enter the error: function

$.ajax({
url: "google.com/api/doesnotexists",
dataType: "jsonp",
timeout: 5000,

success: function (parsed_json) {
console.log(parsed_json);
},

error: function (parsedjson, textStatus, errorThrown) {
console.log("parsedJson: " + JSON.stringify(parsedjson));

$('body').append(
    "parsedJson status: " + parsedjson.status + '</br>' + 
    "errorStatus: " + textStatus + '</br>' + 
    "errorThrown: " + errorThrown);        

 }
});

jsfiddle - Handle Errors with jquery ajax call and JSONP dataType - Error 404

Phemia answered 4/10, 2013 at 16:6 Comment(3)
Looking at this it initially appears to work, but unfortunately using "google.com/api/doesnotexists" will make jQuery request http://fiddle.jshell.net/_display/google.com, instead of google.com. If you prefix the url with http you will see the correct behaviour, where the timeout is observed and no status is returned.Talbot
Downvoted because I confirmed what @Mig reports; the URL requested is wrong in this example.Coppage
Good example, this worked for me, down-vote because of a pseudo URL? really!Toplevel
T
2

I'm building a fragile JS project that uses jquery-jsonp, and came up with a dual-jsonp/ajax approach that handles errors no matter which method ends up being used.

function authenticate(user, pass) {
    var ajax = ($.jsonp || $.ajax)({
        'url': /* your auth url */,
        'data': { /* user, pass, ... */ },
        'contentType': "application/javascript",
        'dataType': 'jsonp',
        'callbackParameter': 'callback'  // $.jsonp only; $.ajax uses 'jsonpCallback'
    });
    ajax.done(function (data) {
        // your success events
    });
    ajax.fail(function (jqXHR, textStatus, errorThrown) {
        // $.jsonp calls this func as function (jqXHR, textStatus)
        // and $.ajax calls this func with the given signature
        console.error('AJAX / JSONP ' + textStatus + ': ' +
            (errorThrown || jqXHR.url));
    });
}

Since both jquery-jsonp and $.ajax support the jQuery Deferred specification, we can merge the two error handlers together, handling 400 and 500-series errors, as well as lookup timeouts.

Thistle answered 30/9, 2013 at 20:23 Comment(0)
T
0

Old question but I had the same problem. Here is a solution that worked for me.

If you own the domain you shoot your request at, you can set a variable in the response and check for it on the client side.

Server Side:

SERVER_RESPONSE=true; Callback(parameter1, parameter2);

Client Side:

if(typeof SERVER_RESPONSE === 'undefined'){
  console.log('No Response, maybe server is down');
}
else{
  console.log('Got a server response');
}
Tequilater answered 6/5, 2014 at 15:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.