Fehlerbehandlung bei getJSON-Aufrufen

192

Wie können Sie mit Fehlern in einem getJSON-Aufruf umgehen? Ich versuche mit jsonp auf einen domänenübergreifenden Skriptdienst zu verweisen. Wie registriere ich eine Fehlermethode?

Ajay
quelle
Scheint ein Duplikat des Fehlers
Hippietrail
Ajay, warum nicht überlegen, die richtige Antwort zu markieren?
Ionică Bizău
@ IonicăBizău Markiert es jetzt. Ich habe das für eine Weile aus den Augen verloren. Die beste Antwort ist nicht JSONP. Wie von Ben Shelock hervorgehoben, gibt es meines Erachtens keinen unterstützten Fehlerbehandler.
Ajay

Antworten:

277

$.getJSON() ist eine Art Abstraktion eines regulären AJAX-Aufrufs, bei dem Sie angeben müssen, dass Sie eine JSON-codierte Antwort wünschen.

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

Sie können Fehler auf zwei Arten behandeln: generisch (indem Sie Ihre AJAX-Aufrufe konfigurieren, bevor Sie sie tatsächlich aufrufen) oder spezifisch (mit Methodenkette).

"generisch" wäre so etwas wie:

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

Und der "spezifische" Weg:

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });
Luciano Costa
quelle
Nein! Sie können dort gehen, wie Sie möchten. Weitere Informationen finden Sie in den Dokumenten: http://api.jquery.com/jQuery.ajax
Luciano Costa
5
Beachten Sie, dass dies jQuery 1.5+ erfordert (ich habe versucht, es mit jQuery 1.3 zum Laufen zu bringen und mich gefragt, warum es sich über eine ungültige Methode beschwert hat :-)
Kenyee
24
Das OP fragt speziell nach Cross-Site, da JSONPes getJSONin einem solchen Fall die error()Funktion nicht aufruft . Ich habe das gleiche Problem. Ich denke, es JSONPhängt damit zusammen, wie völlig anders behandelt wird als bei normalen AJAXAnrufen, jQueryobwohl getJSONbeide behandelt werden. JSONwird mit einem XMLHTTPRequestObjekt ausgeführt, JSONPerfolgt jedoch durch dynamisches Hinzufügen eines <script>Tags zu den Seiten HEAD.
Hippietrail
3
Im jQuery-Dokument heißt es: "Hinweis: Dieser Handler wird nicht für domänenübergreifende Skript- und JSONP-Anforderungen aufgerufen." api.jquery.com/jQuery.ajax > Fehler
OneWorld
10
"Die in jQuery 1.5 eingeführten Rückrufmethoden jqXHR.success (), jqXHR.error () und jqXHR.complete () sind ab jQuery 1.8 veraltet. Verwenden Sie jqXHR.done (), jqXHR, um Ihren Code für das eventuelle Entfernen vorzubereiten .fail () und stattdessen jqXHR.always (). "
Skorunka František
86

Jemand gibt Luciano diese Punkte :) Ich habe gerade seine Antwort getestet - hatte eine ähnliche Frage - und perfekt funktioniert ...

Ich addiere sogar meine 50 Cent:

.error(function(jqXHR, textStatus, errorThrown) {
        console.log("error " + textStatus);
        console.log("incoming Text " + jqXHR.responseText);
    })
frenetix
quelle
3
War dies mit standortübergreifendem JSONP oder mit demselben standortbezogenen JSON?
Hippietrail
28
Gute Antwort! Nur ein Hinweis zu .error: Es wird in jQuery 1.8 veraltet sein, verwenden Sie also .fail
Anatoly Mironov
73

Hier ist meine Ergänzung.

Von http://www.learnjavascript.co.uk/jq/reference/ajax/getjson.html und der offiziellen Quelle

" Die in jQuery 1.5 eingeführten Rückrufmethoden jqXHR.success (), jqXHR.error () und jqXHR.complete () sind ab jQuery 1.8 veraltet. Verwenden Sie jqXHR.done (), jqXHR, um Ihren Code für das eventuelle Entfernen vorzubereiten .fail () und stattdessen jqXHR.always (). "

Ich habe das gemacht und hier ist Lucianos aktualisiertes Code-Snippet:

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

Und mit Fehlerbeschreibung und Anzeige aller JSON-Daten als Zeichenfolge:

$.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!'); });

Wenn Sie keine Warnungen mögen, ersetzen Sie sie durch 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!'); });
user2314737
quelle
Wie ist die chronologische Reihenfolge von erledigt, fehlgeschlagen, immer und der Code in getJSON?
TheLogicGuy
Hinweis: console.log ist in älteren Browsern nicht als IE7 implementiert! Nur für den Fall, dass Sie es benutzen!
MadMad666
12

Ich weiß, es ist schon eine Weile her, dass jemand hier geantwortet hat und das Poster wahrscheinlich bereits seine Antwort entweder von hier oder von irgendwo anders erhalten hat. Ich denke jedoch, dass dieser Beitrag jedem helfen wird, der nach einer Möglichkeit sucht, Fehler und Zeitüberschreitungen zu verfolgen, während er getJSON-Anfragen ausführt. Deshalb unten meine Antwort auf die Frage

Die getJSON-Struktur lautet wie folgt (auf http://api.jqueri.com ):

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

Die meisten Leute implementieren das mit

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

Wenn sie die URL var verwenden, um einen Link zu den JSON-Daten bereitzustellen, das Datenende als Ort zum Hinzufügen der "?callback=?"und anderer Variablen , die gesendet werden müssen, um die richtigen JSON-Daten zurückzugeben, und die Erfolgsfunktion als Funktion zum Verarbeiten der Daten .

Sie können jedoch die Status- und xhr-Variablen zu Ihrer Erfolgsfunktion hinzufügen. Die Statusvariable enthält eine der folgenden Zeichenfolgen: "Erfolg", "Nicht geändert", "Fehler", "Zeitüberschreitung" oder "Parsererror", und die Variable xhr enthält das zurückgegebene XMLHttpRequest-Objekt ( auf w3schools gefunden ).

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

Auf diese Weise ist es einfach, Zeitüberschreitungen und Fehler zu verfolgen, ohne einen benutzerdefinierten Zeitüberschreitungs-Tracker implementieren zu müssen, der nach Abschluss einer Anforderung gestartet wird.

Ich hoffe, dies hilft jemandem, der noch nach einer Antwort auf diese Frage sucht.

Tom Groentjes
quelle
2
Das funktioniert nicht. Der "Erfolgs" -Rückruf wird, wie der Name schon sagt, nur beim Erfolg aufgerufen. (Also bin ich mir nicht sicher, wofür der "Status" -Parameter ist ...)
jwelsh
4

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

Es ist in jQuery 2.x behoben; In jQuery 1.x erhalten Sie niemals einen Fehlerrückruf

Pavlo O.
quelle
1

Ich war mit demselben Problem konfrontiert, aber anstatt Rückrufe für eine fehlgeschlagene Anforderung zu erstellen, habe ich einfach einen Fehler mit dem json-Datenobjekt zurückgegeben.

Wenn möglich, scheint dies die einfachste Lösung zu sein. Hier ist ein Beispiel des von mir verwendeten Python-Codes. (Mit Flask jsonify f Flask und 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.")

Dann können Sie Javascript wie folgt überprüfen.

$.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
    }
});
Nick Woodhams
quelle
Dies ist in Ordnung für Fehler, die auf dem Server auftreten, wird jedoch nicht erfasst, wenn der Anruf den Server nicht erreichen kann oder wenn ein Fehler ausgelöst wird, bevor er auf den Servercode trifft, z. B. wenn ein MVC-Benutzer nicht mehr authentifiziert ist.
Lee Oades
1

Warum nicht

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

??

Einzelheiten zur verwendeten .fail()Methode (jQuery 1.5+) finden Sie unter http://api.jquery.com/jQuery.ajax/#jqXHR

Da das jqXHRvon der Funktion zurückgegeben wird, mag eine Verkettung wie

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

ist möglich.

phil294
quelle
0

In einigen Fällen kann es zu Problemen bei der Synchronisierung mit dieser Methode kommen. Ich habe den Rückrufaufruf in eine setTimeoutFunktion geschrieben und er hat synchron gut funktioniert =)

Z.B:

function obterJson(callback) {


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

    setTimeout(function(){
        callback(data);
    },0);
}
Alex Alonso
quelle