JQuery Ajax (JSONP)는 타임 아웃을 무시하고 오류 이벤트를 시작하지 않습니다.

StackOverflow https://stackoverflow.com/questions/1002367

문제

기본 오류 처리를 추가하기 위해 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;
}

이 솔루션에 대해 어떻게 생각하십니까? 호환성 문제를 일으킬 가능성이 있습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top