Błąd obsługi w połączeniach getJSON

192

Jak radzić sobie z błędami w wywołaniu getJSON? Próbuję odwołać się do usługi skryptów między domenami za pomocą jsonp. Jak zarejestrować metodę błędu?

Ajay
źródło
Ajay, dlaczego nie rozważyć zaznaczenia poprawnej odpowiedzi?
Ionică Bizău
@ IonicăBizău Oznaczono to teraz. Po prostu straciłem z tego świadomość. Najważniejsza odpowiedź nie mówi o JSONP. Jak zauważył Ben Shelock, nie ma obsługiwanego modułu obsługi błędów, w co wierzę ...
Ajay

Odpowiedzi:

277

$.getJSON() jest rodzajem abstrakcji zwykłego wywołania AJAX, w którym musisz powiedzieć, że chcesz odpowiedzi w formacie JSON.

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

Błędy można obsługiwać na dwa sposoby: ogólnie (konfigurując wywołania AJAX przed ich faktycznym wywołaniem) lub konkretnie (za pomocą łańcucha metod).

„rodzajowy” mógłby wyglądać następująco:

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

I „specyficzny” sposób:

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });
Luciano Costa
źródło
Ups! Możesz tam iść, jak chcesz. Zajrzyj do dokumentacji, aby uzyskać bardziej szczegółową pomoc: http://api.jquery.com/jQuery.ajax
Luciano Costa
5
Zauważ, że wymaga to jQuery 1.5+ (próbowałem uruchomić go z jQuery 1.3 i zastanawiałem się, dlaczego narzeka na niewłaściwą metodę :-)
kenyee
24
OP pyta konkretnie o cross-site, JSONPponieważ wydaje się, że getJSONw takim przypadku nie wywołuje error()funkcji. Mam ten sam problem. Myślę, że ma to związek z tym, jak JSONPjest obsługiwane zupełnie inaczej niż normalne AJAXpołączenia jQuerypomimo getJSONobsługi obu. JSONodbywa się za pomocą XMLHTTPRequestobiektu, ale JSONPodbywa się to poprzez dynamiczne dodawanie <script>znacznika do strony HEAD.
hippietrail,
3
Dokument jQuery Doc mówi: „Uwaga: ten moduł obsługi nie jest wywoływany dla skryptów między domenami i żądań JSONP”. api.jquery.com/jQuery.ajax > error
OneWorld
10
„Metody wywołania zwrotnego jqXHR.success (), jqXHR.error () i jqXHR.complete () wprowadzone w jQuery 1.5 są przestarzałe od jQuery 1.8. Aby przygotować kod do ich ewentualnego usunięcia, użyj jqXHR.done (), jqXHR zamiast tego .fail () i jqXHR.always (). "
Skorunka František
86

Ktoś dał Luciano te punkty :) Właśnie przetestowałem jego odpowiedź - miałem podobne pytanie - i działałem idealnie ...

Dodaję nawet 50 centów:

.error(function(jqXHR, textStatus, errorThrown) {
        console.log("error " + textStatus);
        console.log("incoming Text " + jqXHR.responseText);
    })
frenetix
źródło
3
Czy było tak z JSONP między witrynami czy z JSON tej samej witryny?
hippietrail,
28
Niezła odpowiedź! Tylko uwaga na temat .error: Będzie przestarzała w jQuery 1.8, więc użyj .fail
Anatoly Mironov
73

Oto mój dodatek.

Od http://www.learnjavascript.co.uk/jq/reference/ajax/getjson.html i oficjalnego źródła

Metody wywołania zwrotnego jqXHR.success (), jqXHR.error () i jqXHR.complete () wprowadzone w jQuery 1.5 są przestarzałe od jQuery 1.8. Aby przygotować kod do ich ewentualnego usunięcia, użyj jqXHR.done (), jqXHR zamiast tego .fail () i jqXHR.always (). "

Zrobiłem to i oto zaktualizowany fragment kodu 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!'); });

Oraz z opisem błędu i pokazaniem wszystkich danych JSON w postaci ciągu:

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

Jeśli nie lubisz powiadomień, zamień je na 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!'); });
użytkownik2314737
źródło
jaki jest chronologiczny porządek: zrobione, niepowodzenie, zawsze i kod w getJSON?
TheLogicGuy
Uwaga: plik console.log nie jest zaimplementowany w starszych przeglądarkach jak IE7! Na wszelki wypadek!
MadMad666
12

Wiem, że minęło trochę czasu, odkąd ktoś odpowiedział tutaj, a plakat prawdopodobnie już otrzymał odpowiedź albo stąd, albo gdzie indziej. Myślę jednak, że ten post pomoże każdemu, kto szuka sposobu śledzenia błędów i przekroczeń limitu czasu podczas wykonywania żądań getJSON. Dlatego poniżej mojej odpowiedzi na pytanie

Struktura getJSON jest następująca (znaleziona na http://api.jqueri.com ):

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

większość ludzi wdraża to za pomocą

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

tam, gdzie używają url var, aby udostępnić link do danych JSON, datatosend jako miejsce do dodania "?callback=?"i innych zmiennych, które należy wysłać, aby uzyskać prawidłowe dane JSON, oraz funkcję powodzenia jako funkcję przetwarzania danych .

Możesz jednak dodać zmienne status i xhr do swojej funkcji sukcesu. Zmienna statusu zawiera jeden z następujących ciągów: „sukces”, „niezmodyfikowany”, „błąd”, „limit czasu” lub „parsererror”, a zmienna xhr zawiera zwrócony obiekt XMLHttpRequest ( znaleziony w 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");
    }         
});

W ten sposób można łatwo śledzić limity czasu i błędy bez konieczności implementowania niestandardowego modułu do śledzenia limitów czasu, który jest uruchamiany po wykonaniu żądania.

Mam nadzieję, że pomoże to komuś, kto wciąż szuka odpowiedzi na to pytanie.

Tom Groentjes
źródło
2
To nie działa Callback „sukces”, jak sama nazwa wskazuje, jest wywoływany tylko w przypadku sukcesu. (Więc nie jestem pewien, jaki jest parametr „status” dla ...)
jwelsh
4

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

Zostało to naprawione w jQuery 2.x; W jQuery 1.x nigdy nie otrzymasz wywołania zwrotnego błędu

Pavlo O.
źródło
1

Miałem do czynienia z tym samym problemem, ale zamiast tworzyć wywołania zwrotne dla nieudanego żądania, po prostu zwróciłem błąd z obiektem danych json.

Jeśli to możliwe, wydaje się to najłatwiejszym rozwiązaniem. Oto próbka użytego kodu Python. (Korzystanie z Flask, jsonify f Flask i 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.")

Następnie możesz sprawdzić Javascript w ten sposób;

$.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
źródło
Jest to odpowiednie w przypadku błędów, które występują na serwerze, ale nie jest rejestrowane, gdy połączenie nie może dotrzeć do serwera lub jeśli wystąpi błąd, zanim trafi on do kodu serwera, na przykład jeśli użytkownik MVC nie jest już uwierzytelniony.
Lee Oades,
1

Dlaczego nie

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

??

Aby uzyskać szczegółowe informacje na temat zastosowanej .fail()metody (jQuery 1.5+), zobacz http://api.jquery.com/jQuery.ajax/#jqXHR

Ponieważ funkcja jqXHRjest zwracana przez funkcję, podobny jest łańcuch

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

jest możliwe.

phil294
źródło
0

W niektórych przypadkach możesz napotkać problem z synchronizacją z tą metodą. Napisałem wywołanie zwrotne w setTimeoutfunkcji i zadziałało synchronicznie dobrze =)

NA PRZYKŁAD:

function obterJson(callback) {


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

    setTimeout(function(){
        callback(data);
    },0);
}
Alex Alonso
źródło
0

To dość stary wątek, ale pojawia się w wyszukiwarce Google, więc pomyślałem, że dodam odpowiedź jQuery 3, używając obietnic. Ten fragment pokazuje również:

  • Nie musisz już przełączać się na $ .ajax, aby przekazać swój token na okaziciela
  • Używa .then (), aby upewnić się, że możesz przetwarzać synchronicznie dowolny wynik (natknąłem się na ten problem. Zawsze () odpalanie wywołania zwrotnego zbyt szybko - chociaż nie jestem pewien, czy to w 100% prawda)
  • Używam .always (), aby po prostu pokazać wynik, czy to pozytywny czy negatywny
  • W funkcji .always () aktualizuję dwa cele kodem stanu HTTP i treścią wiadomości

Fragment kodu to:

    $.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);
    });
Z Orbonii
źródło