Aby dodać trochę podstawowej obsługi błędów, chciałem przepisać fragment kodu, który wykorzystywał $ .getJSON jQuery do ściągnięcia niektórych zdjęć z Flickr. Powodem tego jest to, że $ .getJSON nie obsługuje błędów ani nie działa z limitami czasu.
Ponieważ $ .getJSON to tylko opakowanie wokół $ .ajax, postanowiłem przepisać to i zaskoczyć, działa bezbłędnie.
Teraz jednak zaczyna się zabawa. Kiedy celowo wywołuję błąd 404 (zmieniając adres URL) lub powoduję przekroczenie limitu czasu sieci (przez brak połączenia z interwebami), zdarzenie błędu w ogóle się nie uruchamia. Nie wiem, co robię źle. Pomoc jest bardzo ceniona.
Oto kod:
$(document).ready(function(){
// var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne"; // correct URL
var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne_______"; // this should throw a 404
$.ajax({
url: jsonFeed,
data: { "lang" : "en-us",
"format" : "json",
"tags" : "sunset"
},
dataType: "jsonp",
jsonp: "jsoncallback",
timeout: 5000,
success: function(data, status){
$.each(data.items, function(i,item){
$("<img>").attr("src", (item.media.m).replace("_m.","_s."))
.attr("alt", item.title)
.appendTo("ul#flickr")
.wrap("<li><a href=\"" + item.link + "\"></a></li>");
if (i == 9) return false;
});
},
error: function(XHR, textStatus, errorThrown){
alert("ERREUR: " + textStatus);
alert("ERREUR: " + errorThrown);
}
});
});
Dodam, że to pytanie zostało zadane, gdy jQuery był w wersji 1.4.2
<script>
tagi JavaScript , które są wstawiane dynamicznie. W związku z tym jedyną rzeczą, którą możesz wiedzieć, jest to, że żądanie nie powiodło się, a nie jaki był kod stanu. Jeśli chcesz uzyskać kody statusu, musisz użyć tradycyjnych żądań Ajax lub innych technik międzydomenowych.Jest to znane ograniczenie natywnej implementacji jsonp w jQuery. Poniższy tekst pochodzi z IBM DeveloperWorks
Jednak w GoogleCode dostępna jest wtyczka jsonp, która zapewnia obsługę obsługi błędów. Aby rozpocząć, po prostu wprowadź następujące zmiany w kodzie.
Możesz go pobrać lub po prostu dodać odwołanie do skryptu do wtyczki.
<script type="text/javascript" src="http://jquery-jsonp.googlecode.com/files/jquery.jsonp-1.0.4.min.js"> </script>
Następnie zmodyfikuj wywołanie Ajax, jak pokazano poniżej:
$(function(){ //var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne"; // correct URL var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne_______"; // this should throw a 404 $.jsonp({ url: jsonFeed, data: { "lang" : "en-us", "format" : "json", "tags" : "sunset" }, dataType: "jsonp", callbackParameter: "jsoncallback", timeout: 5000, success: function(data, status){ $.each(data.items, function(i,item){ $("<img>").attr("src", (item.media.m).replace("_m.","_s.")) .attr("alt", item.title) .appendTo("ul#flickr") .wrap("<li><a href=\"" + item.link + "\"></a></li>"); if (i == 9) return false; }); }, error: function(XHR, textStatus, errorThrown){ alert("ERREUR: " + textStatus); alert("ERREUR: " + errorThrown); } }); });
źródło
Rozwiązanie, jeśli utkniesz z jQuery 1.4:
var timeout = 10000; var id = setTimeout( errorCallback, timeout ); $.ajax({ dataType: 'jsonp', success: function() { clearTimeout(id); ... } });
źródło
.abort()
oczekującego jqXHR po upływie limitu czasu może być lepszym sposobem.Może to być „znane” ograniczenie jQuery; jednak wydaje się, że nie jest to dobrze udokumentowane. Spędziłem dziś około 4 godzin, próbując zrozumieć, dlaczego mój limit czasu nie działa.
Przerzuciłem się na jquery.jsonp i działało to przyjemnie. Dziękuję Ci.
źródło
Wydaje się, że został rozwiązany w jQuery 1.5. Wypróbowałem powyższy kod i otrzymałem oddzwonienie.
Mówię „wydaje się”, ponieważ dokumentacja wywołania zwrotnego błędu dla jQuery.ajax () nadal zawiera następującą notatkę:
źródło
JQuery jQuery plugin-jsonp wymienione w Jose Basilio za odpowiedź można teraz znaleźć na GitHub .
Niestety dokumentacja jest nieco spartańska, więc podałem prosty przykład:
$.jsonp({ cache: false, url: "url", callbackParameter: "callback", data: { "key" : "value" }, success: function (json, textStatus, xOptions) { // handle success - textStatus is "success" }, error: function (xOptions, textStatus) { // handle failure - textStatus is either "error" or "timeout" } });
Ważne Uwzględnij parametr callbackParameter w wywołaniu $ .jsonp (), w przeciwnym razie stwierdziłem, że funkcja callback nigdy nie zostanie wstrzyknięta do ciągu zapytania wywołania usługi (aktualna od wersji 2.4.0 jquery-jsonp).
Wiem, że to pytanie jest stare, ale problem obsługi błędów za pomocą JSONP nadal nie jest „rozwiązany”. Mamy nadzieję, że ta aktualizacja pomoże innym, ponieważ to pytanie zajmuje najwyższe miejsce w Google pod względem „obsługi błędów jquery jsonp”.
źródło
A co ze słuchaniem zdarzenia onerror w scenariuszu? Miałem ten problem i rozwiązałem go, łatając metodę jquery, w której został utworzony tag script. Oto interesujący fragment kodu:
// Attach handlers for all browsers script.onload = script.onreadystatechange = function( _, isAbort ) { if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { cleanup(); // Callback if not abort if ( !isAbort ) { callback( 200, "success" ); } } }; /* ajax patch : */ script.onerror = function(){ cleanup(); // Sends an inappropriate error, still better than nothing callback(404, "not found"); }; function cleanup(){ // Handle memory leak in IE script.onload = script.onreadystatechange = null; // Remove the script if ( head && script.parentNode ) { head.removeChild( script ); } // Dereference the script script = undefined; }
Co myślisz o tym rozwiązaniu? Czy może to spowodować problemy ze zgodnością?
źródło