Gestione degli errori nelle chiamate getJSON


192

Come è possibile gestire gli errori in una chiamata getJSON? Sto cercando di fare riferimento a un servizio di script tra domini utilizzando jsonp, come si registra un metodo di errore?



Ajay, perché non considerare di contrassegnare la risposta corretta?
Ionică Bizău,

@ IonicăBizău Contrassegnato ora. Ho appena perso traccia di questo per un po '. La risposta migliore non sta parlando di JSONP. Come sottolineato da Ben Shelock, non esiste un gestore degli errori supportato è ciò in cui credo ..
Ajay

Risposte:


277

$.getJSON() è una sorta di astrazione di una normale chiamata AJAX in cui dovresti dire che vuoi una risposta codificata JSON.

$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

È possibile gestire gli errori in due modi: genericamente (configurando le chiamate AJAX prima di chiamarle effettivamente) o specificamente (con la catena di metodi).

'generico' sarebbe qualcosa del tipo:

$.ajaxSetup({
      "error":function() { alert("error");  }
});

E il modo "specifico":

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });

PON! Puoi andare come vuoi lì. Dai un'occhiata alla documentazione per un aiuto più dettagliato: http://api.jquery.com/jQuery.ajax
Luciano Costa,

5
Nota che questo richiede jQuery 1.5+ (stava provando a farlo funzionare con jQuery 1.3 e chiedendosi perché si lamentasse del metodo non valido :-)
Kenyee,

24
L'OP sta chiedendo specificamente di cross-site JSONPin quanto getJSONin tal caso non chiama la error()funzione. Sto avendo lo stesso problema. Immagino che abbia a che fare con il modo in cui JSONPviene gestita totalmente diversa dalle normali AJAXchiamate jQuerynonostante la getJSONgestione di entrambe. JSONviene fatto con un XMLHTTPRequestoggetto ma JSONPviene fatto aggiungendo dinamicamente un <script>tag alle pagine HEAD.
hippietrail,

3
Il documento jQuery dice "Nota: questo gestore non è chiamato per richieste tra script di domini e JSONP". api.jquery.com/jQuery.ajax > errore
OneWorld

10
"I metodi di callback jqXHR.success (), jqXHR.error () e jqXHR.complete () introdotti in jQuery 1.5 sono obsoleti a partire da jQuery 1.8. Per preparare il codice per la loro eventuale rimozione, utilizzare jqXHR.done (), jqXHR .fail () e jqXHR.always () invece. "
Skorunka František,

86

Qualcuno dà a Luciano questi punti :) Ho appena testato la sua risposta - aveva una domanda simile - e ho funzionato perfettamente ...

Aggiungo anche i miei 50 centesimi:

.error(function(jqXHR, textStatus, errorThrown) {
        console.log("error " + textStatus);
        console.log("incoming Text " + jqXHR.responseText);
    })

3
Era questo con JSONP tra siti o con lo stesso sito JSON?
hippietrail,

28
Bella risposta! Solo una nota su .error: diventerà obsoleta in jQuery 1.8, quindi usa .fail
Anatoly Mironov,

73

Ecco la mia aggiunta.

Da http://www.learnjavascript.co.uk/jq/reference/ajax/getjson.html e dalla fonte ufficiale

" I metodi di callback jqXHR.success (), jqXHR.error () e jqXHR.complete () introdotti in jQuery 1.5 sono obsoleti a partire da jQuery 1.8. Per preparare il codice per la loro eventuale rimozione, utilizzare jqXHR.done (), jqXHR .fail () e jqXHR.always () invece. "

L'ho fatto ed ecco lo snippet di codice aggiornato di Luciano:

$.getJSON("example.json", function() {
  alert("success");
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function() { alert('getJSON request failed! '); })
.always(function() { alert('getJSON request ended!'); });

E con la descrizione dell'errore più mostrando tutti i dati JSON come una stringa:

$.getJSON("example.json", function(data) {
  alert(JSON.stringify(data));
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });

Se non ti piacciono gli avvisi, sostituiscili con console.log

$.getJSON("example.json", function(data) {
  console.log(JSON.stringify(data));
})
.done(function() { console.log('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { console.log('getJSON request failed! ' + textStatus); })
.always(function() { console.log('getJSON request ended!'); });

qual è l'ordine cronologico di done, fail, always e il codice all'interno di getJSON?
TheLogicGuy

nota: console.log non è implementato nei browser meno recenti come IE7! Nel caso in cui lo usi!
MadMad666,

12

So che è passato un po 'di tempo da quando qualcuno ha risposto qui e il poster probabilmente ha già ottenuto la sua risposta da qui o da qualche altra parte. Tuttavia, penso che questo post aiuterà chiunque cerchi un modo per tenere traccia di errori e timeout durante le richieste getJSON. Pertanto di seguito la mia risposta alla domanda

La struttura getJSON è la seguente (disponibile su http://api.jqueri.com ):

$(selector).getJSON(url,data,success(data,status,xhr))

la maggior parte delle persone lo implementa

$.getJSON(url, datatosend, function(data){
    //do something with the data
});

dove usano l'URL var per fornire un collegamento ai dati JSON, il datatosend come luogo in cui aggiungere il file "?callback=?" altre variabili che devono essere inviate per ottenere la restituzione dei dati JSON corretti e la funzione success come funzione per l'elaborazione dei dati .

Puoi comunque aggiungere lo stato e le variabili xhr nella tua funzione di successo. La variabile status contiene una delle seguenti stringhe: "success", "notmodified", "error", "timeout" o "parsererror" e la variabile xhr contiene l'oggetto XMLHttpRequest restituito ( trovato su w3schools )

$.getJSON(url, datatosend, function(data, status, xhr){
    if (status == "success"){
        //do something with the data
    }else if (status == "timeout"){
        alert("Something is wrong with the connection");
    }else if (status == "error" || status == "parsererror" ){
        alert("An error occured");
    }else{
        alert("datatosend did not change");
    }         
});

In questo modo è facile tenere traccia di timeout ed errori senza dover implementare un tracker di timeout personalizzato che viene avviato al termine di una richiesta.

Spero che questo aiuti qualcuno ancora alla ricerca di una risposta a questa domanda.


2
Questo non funziona Il callback "successo", come suggerisce il nome, è chiamato solo al successo. (Quindi non sono sicuro di quale sia il parametro "status" per ...)
jwelsh il

4

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })

È stato risolto in jQuery 2.x; In jQuery 1.x non si riceverà mai un errore di richiamata


1

Ho dovuto affrontare lo stesso problema, ma anziché creare callback per una richiesta non riuscita, ho semplicemente restituito un errore con l'oggetto dati json.

Se possibile, questa sembra la soluzione più semplice. Ecco un esempio del codice Python che ho usato. (Usando Flask, Flask's jsonify fe SQLAlchemy)

try:
    snip = Snip.query.filter_by(user_id=current_user.get_id(), id=snip_id).first()
    db.session.delete(snip)
    db.session.commit()
    return jsonify(success=True)
except Exception, e:
    logging.debug(e)
    return jsonify(error="Sorry, we couldn't delete that clip.")

Quindi puoi controllare Javascript in questo modo;

$.getJSON('/ajax/deleteSnip/' + data_id,
    function(data){
    console.log(data);
    if (data.success === true) {
       console.log("successfully deleted snip");
       $('.snippet[data-id="' + data_id + '"]').slideUp();
    }
    else {
       //only shows if the data object was returned
    }
});

Questo va bene per gli errori che si verificano all'interno del server, ma non acquisisce quando la chiamata non può raggiungere il server o se si verifica un errore prima che colpisca il codice del server, come se un utente MVC non è più autenticato.
Lee Oades,

1

Perchè no

getJSON('get.php',{cmd:"1", typeID:$('#typesSelect')},function(data) {
    // ...
});

function getJSON(url,params,callback) {
    return $.getJSON(url,params,callback)
        .fail(function(jqXMLHttpRequest,textStatus,errorThrown) {
            console.dir(jqXMLHttpRequest);
            alert('Ajax data request failed: "'+textStatus+':'+errorThrown+'" - see javascript console for details.');
        })
}

??

Per dettagli sul .fail()metodo utilizzato (jQuery 1.5+), consultare http://api.jquery.com/jQuery.ajax/#jqXHR

Dato che il jqXHRè restituito dalla funzione, un concatenamento simile

$.when(getJSON(...)).then(function() { ... });

è possibile.


0

In alcuni casi, potresti riscontrare un problema di sincronizzazione con questo metodo. Ho scritto la chiamata di richiamata all'interno di asetTimeout funzione e ha funzionato in modo sincrono bene =)

PER ESEMPIO:

function obterJson(callback) {


    jqxhr = $.getJSON(window.location.href + "js/data.json", function(data) {

    setTimeout(function(){
        callback(data);
    },0);
}

0

Questa è una discussione piuttosto vecchia, ma emerge dalla ricerca di Google, quindi ho pensato di aggiungere una risposta jQuery 3 usando le promesse. Questo frammento mostra anche:

  • Non è più necessario passare a $ .ajax per passare il token al portatore
  • Utilizza .then () per essere sicuro di poter elaborare in modo sincrono qualsiasi risultato (mi sono imbattuto in questo problema. Il callback ha sempre attivato il callback troppo presto , anche se non sono sicuro che fosse vero al 100%)
  • Sto usando .always () per mostrare semplicemente il risultato positivo o negativo
  • Nella funzione .always () sto aggiornando due target con il codice di stato HTTP e il corpo del messaggio

Lo snippet di codice è:

    $.getJSON({
         url: "https://myurl.com/api",
         headers: { "Authorization": "Bearer " + user.access_token}
    }).then().always(   function (data, textStatus) {
        $("#txtAPIStatus").html(data.status);
        $("#txtAPIValue").html(data.responseText);
    });
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.