2011-10-07 5 views
13

ho costruito un banco di prova di una chiamata AJAX (jQuery 1.6.2) che assomiglia a:Gestione degli errori jQuery.ajax per cross-domain jsonp chiamate

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); 
}); 

e il corrispondente file di test.php assomiglia:

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"})'; 
} 

Anche se la jQuery documentation indica che il gestore degli errori per jsonp chiamate è mai sparato, questo script funziona proprio come volevo. Effettua quattro chiamate "non riuscite" a test.php che restituiscono 503 errori, e quindi test() si richiama in modo ricorsivo x incrementale fino a quando la chiamata ajax è "riuscita" e i dati vengono inviati alla console.

Quindi il mio banco di prova sopra funziona, ma il mio codice attuale non funziona, che sembra più simile al seguente:

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); 
}; 

Come si può vedere, questo loop attraverso 5 diversi sottodomini che sono in realtà solo mirror dello stesso dominio, ma poiché update_state.php può richiedere fino a 30 secondi per essere completato, questo richiede un processo di 25 minuti fino a meno di tre minuti. Il problema è che il server martellante causa alcune delle richieste ajax di fallire con un errore 503. Nel mio caso di test questo è stato gestito senza problemi, ma nel mio secondo esempio, il gestore degli errori non sembra mai essere chiamato.

Non riesco a capire perché il test case funziona come mi aspetto e il secondo no. Qualche idea?

+0

provato a cambiare fino a jQuery 1.6. 4 con lo stesso risultato – morphatic

+0

potrebbe essere che usare php 'header()' per restituire 503 si comporta diversamente da un "effettivo" 503? Ho esaminato le intestazioni HTTP di entrambi i casi e sembrano identici a me ... – morphatic

+0

Nel primo esempio, si incrementa x ogni volta (x ++;) nel gestore degli errori. Nel secondo, non si incrementa l'indice ++; questa è l'unica differenza evidente che posso vedere. – Kato

risposta

2

Nel tuo caso prova si cambia teh valore x für ogni chiamata ...

Nella altro codice che si sta inviando lo stesso valore di indice. Che restituirà lo stesso risultato, invece di "revolving" attraverso i sottodomini ...

error: function() { 
     index++; 
     updateState(index, state); 
    } 
+1

Il parametro index viene automaticamente incrementato di la chiamata alla funzione jQuery.each() sulla penultima riga. Buona idea, ma non credo sia questo il problema. – morphatic

+0

Capisco che l'indice sia stato modificato dalla chiamata alla funzione .each(). Tuttavia ciò non influisce sull'indice chiamato nel caso di errore. Per ogni stato dell'array, si chiama la funzione, che si chiama in caso di errore ... – blindfold

2

Se per caso si sta utilizzando Internet Explorer per testare il primo caso e, eventualmente, FF o Chrome per testare il secondo caso allora che può essere la causa Errore e chiamate globali non vengono invocate per i tipi JSON/JSONP interdominio come documentato dalla funzione jQuery.ajax. Tuttavia, ho notato che vengono ancora chiamati in IE e penso che questo abbia a che fare con jQuery usando IE XMLHttpRequest per fare le chiamate.

Sembra che qualcuno ha gentilmente creato un plugin che gestisce gli errori con le richieste JSONP disponibile qui: http://code.google.com/p/jquery-jsonp/

3

dovrebbe essere in formato simile a questo:

$.ajax({ 
    type: "POST", 
    url: 'http://servername/WebService.svc/GetData?callback=?', 
    dataType: 'jsonp', 
    success: function (data) { 
     //do stuff 
    }, 
    error: function (msg, b, c) { 
    //alert error 
    } 
}); 
+0

JSONP non può essere utilizzato per effettuare richieste POST tra domini. jQuery lo cambierà automaticamente in una richiesta GET. – cesarislaw

+2

Controlla sito web jQuery "Nota: questo gestore non viene chiamato per richieste di JSONP di script e di domini interdominio". – shereifhawary

0
function AjaxRequest(url, params){ 

    return $.ajax({ 
     url:   url, 
     data:   params, 
     dataType:  'jsonp', 

     /* Very important */ 
     contentType: 'application/json', 
    }); 
} 

var test = function(x) { 

    AjaxFeed('http://servername/WebService.svc/GetData', {x: x}) 

    /* Everything worked okay. Hooray */ 
    .done(function(data){ 

     console.log(data); 
    }) 

    /* Oops */ 
    .fail(function(jqXHR, sStatus, oError) { 

     console.log(arguments); 
    }); 
} 

jQuery(window).load(function() { 

    test('test'); 
}