JQuery Ajax (JSONP)는 타임 아웃을 무시하고 오류 이벤트를 시작하지 않습니다.
-
05-07-2019 - |
문제
기본 오류 처리를 추가하기 위해 jQuery의 $ .getJson을 사용하여 Flickr에서 일부 사진을 가져 오는 코드를 다시 작성하고 싶었습니다. 이를 수행하는 이유는 $ .getJson이 오류 처리를 제공하거나 타임 아웃을 사용하지 않기 때문입니다.
$ .getJson은 $ .Ajax 주위의 포장지 일 뿐이므로 나는 그 물건을 다시 쓰고 놀라움을 놀라게하기로 결정했습니다. 그것은 완벽하게 작동합니다.
이제 재미가 시작됩니다. 의도적으로 404 (URL을 변경함으로써)를 유발하거나 네트워크가 타임 아웃을 유발할 때 (인터 웹에 연결되지 않음) 오류 이벤트는 전혀 실행되지 않습니다. 나는 내가 잘못하고있는 것에 대해 상실하고 있습니다. 도움을 주셔서 감사합니다.
코드는 다음과 같습니다.
$(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);
}
});
});
jQuery가 버전 1.4.2에있을 때이 질문이 질문을 받았다고 덧붙이고 싶습니다.
해결책
jQuery 1.5 이상은 JSONP 요청으로 오류 처리를 더 잘 지원합니다. 그러나 사용해야합니다 $.ajax
대신 방법 $.getJSON
. 나를 위해 이것은 다음과 같습니다.
var req = $.ajax({
url : url,
dataType : "jsonp",
timeout : 10000
});
req.success(function() {
console.log('Yes! Success!');
});
req.error(function() {
console.log('Oh noes!');
});
시간 초과는 10 초 후에 성공적인 요청이없는 경우 트릭을 수행하고 오류 처리기를 호출하는 것으로 보입니다.
나는 조금했다 블로그 게시물 이 주제에 대해서도.
다른 팁
이것은 jQuery의 기본 JSONP 구현에서 알려진 한계입니다. 아래 텍스트는 IBM DeveloperWorks
JSONP는 매시업을 구축하는 데 매우 강력한 기술이지만 불행히도 모든 크로스 도메인 커뮤니케이션 요구에 대한 치료법은 아닙니다. 개발 자원을 저지르기 전에 진지하게 고려해야 할 몇 가지 단점이 있습니다. 무엇보다도 JSONP 통화에 대한 오류 처리가 없습니다. 동적 스크립트 삽입이 작동하면 호출됩니다. 그렇지 않다면 아무 일도 일어나지 않습니다. 그것은 단지 조용히 실패합니다. 예를 들어 서버에서 404 오류를 포착 할 수 없습니다. 요청을 취소하거나 다시 시작할 수도 없습니다. 그러나 합리적인 시간을 기다린 후 시간 초과 할 수 있습니다. (미래의 jQuery 버전에는 JSONP 요청에 대한 중단 기능이있을 수 있습니다.)
그러나 JSONP 플러그인을 사용할 수 있습니다 googlecode 오류 처리를 지원합니다. 시작하려면 다음과 같은 코드를 변경하십시오.
다운로드하거나 플러그인에 대한 스크립트 참조를 추가 할 수 있습니다.
<script type="text/javascript"
src="http://jquery-jsonp.googlecode.com/files/jquery.jsonp-1.0.4.min.js">
</script>
그런 다음 아래 그림과 같이 ajax 호출을 수정하십시오.
$(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);
}
});
});
jQuery 1.4에 갇힌 경우 해결책 :
var timeout = 10000;
var id = setTimeout( errorCallback, timeout );
$.ajax({
dataType: 'jsonp',
success: function() {
clearTimeout(id);
...
}
});
이것은 jQuery의 "알려진"한계 일 수 있습니다. 그러나 잘 문서화되지 않은 것 같습니다. 나는 오늘 약 4 시간 동안 시간 초과가 작동하지 않는 이유를 이해하려고 노력했습니다.
나는 전환했다 jQuery.jsonp 그리고 그것은 매력을 좋아했습니다. 고맙습니다.
jQuery 1.5 기준으로 해결 된 것 같습니다. 위의 코드를 시도했는데 콜백을받습니다.
오류 콜백의 문서화가 "인 것 같습니다"라고 말합니다. jQuery.ajax () 여전히 다음과 같은 참고 사항이 있습니다.
참고 :이 핸들러는 크로스 도메인 스크립트 및 JSONP 요청을 요구하지 않습니다.
언급 된 JQuery-JSONP jQuery 플러그인 호세 바실리오의 대답 이제 찾을 수 있습니다 github.
불행히도 문서는 다소 스파르타이므로 간단한 예를 제공했습니다.
$.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"
}
});
중요한 CallbackParameter를 호출 $ .jsonp ()에 포함 시키십시오. 그렇지 않으면 콜백 함수가 서비스 호출의 쿼리 문자열 (JQuery-JSONP의 버전 2.4.0)에 결코 주입되지 않는다는 것을 알았습니다.
나는이 질문이 오래되었음을 알고 있지만 JSONP를 사용한 오류 처리 문제는 여전히 '해결'되지 않습니다. 이 질문이 "JQuery JSONP 오류 처리"에 대한 Google 내에서 최고 순위가 높기 때문에이 업데이트가 다른 업데이트에 도움이되기를 바랍니다.
스크립트의 onerror 이벤트를 듣는 것은 어떻습니까? 스크립트 태그가 생성 된 jQuery의 방법을 패치 하여이 문제를 해결하고 해결했습니다. 흥미로운 코드는 다음과 같습니다.
// 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;
}
이 솔루션에 대해 어떻게 생각하십니까? 호환성 문제를 일으킬 가능성이 있습니까?