Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

handling jQuery.ajax errors for cross-domain jsonp calls

I built a test case of an ajax call (jQuery 1.6.2) that looks like:

jQuery( document ).ready( function( $ ) {
    var test = function( x ) {
        $.ajax({
            url: 'http://www.someotherdomain.com/test.php',
            data: { x: x },
            dataType: 'jsonp',
            crossDomain: true,
            success: function( data ) { 
                console.log( data.name ); 
            },
            error: function() { 
                x++; 
                test( x ); 
            }
        });
    };
    test( 1 );
});

And the corresponding test.php file looks like:

if ( 5 > $_GET[ 'x' ] ) {
    header('HTTP/1.1 503 Service Temporarily Unavailable'); die();
} else {
    header( 'content-type: application/x-javascript' );
    echo $_GET[ 'callback' ] . '({"name":"Morgan"})';
}

Even though the jQuery documentation indicates that the error handler for jsonp calls is never fired, this script works just as I intended. It makes four "unsuccessful" calls to test.php which return 503 errors, and then test() recursively calls itself incrementing x until the ajax call is "successful" and the data is output to the console.

So my test case above works, but my actual code doesn't work, which looks more like the following:

jQuery( document ).ready( function( $ ) {
    var completed = 0;
    var fiftystates; // assume an array of state objects
    var updateState = function( index, state ) {
        var d = index % 5; // for subdomains sub0, sub1, sub2, sub3, sub4
        $.ajax({
            url: 'http://sub' + d + '.mydomain.com/update_state.php',
            data: { state: state.id },
            dataType: 'jsonp',
            crossDomain: true,
            success: function() { 
                completed++; 
                var complete_percent = completed / fiftystates.length * 100;
                $( '#progressbar' ).progressbar( 'value', completed_percent );
            },
            error: function() {
                updateState( index, state );
            }
        }); // end ajax
    }; // end updateState
    $( fiftystates ).each( updateState );
};

As you can see, this loops through 5 different sub-domains which are actually just mirrors of the same domain, but since update_state.php can take up to 30 seconds to complete, this takes a 25 minute process down to less than three minutes. The problem is that the server pounding causes some of the ajax requests to fail with a 503 error. In my test case this was handled with no problem but in my second example, the error handler never seems to get called.

I can't figure out why the test case works as I expect and the second one doesn't. Any ideas?

like image 372
morphatic Avatar asked Oct 07 '11 05:10

morphatic


2 Answers

In your test case you change teh value x für each call...

In the other code you're sending the same index value. Which will return the same result, instead of "revolving" through the subdomains...

    error: function() {
        index++;
        updateState( index, state );
    }
like image 32
blindfold Avatar answered Oct 17 '22 17:10

blindfold


should it be in format like this:

$.ajax({
    type: "POST",
    url: 'http://servername/WebService.svc/GetData?callback=?',
    dataType: 'jsonp',
    success: function (data) {
       //do stuff
    },
    error: function (msg, b, c) {
    //alert error
    }
 });
like image 146
Shawn Avatar answered Oct 17 '22 18:10

Shawn