[jquery] jQuery ajax (jsonp)는 시간 초과를 무시하고 오류 이벤트를 발생시키지 않습니다.

기본적인 오류 처리를 추가하기 위해 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 요청에 대한 중단 기능이있을 수 있습니다.)

그러나 오류 처리를 지원 하는 GoogleCode 에서 사용할 수있는 jsonp 플러그인이 있습니다 . 시작하려면 코드를 다음과 같이 변경하십시오.

다운로드하거나 플러그인에 스크립트 참조를 추가 할 수 있습니다.

<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 요청에 대해 호출되지 않습니다.


답변

Jose Basilio의 답변에 언급 된 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"
        }
    });

중요
$ .jsonp () 호출에 callbackParameter를 포함하십시오. 그렇지 않으면 콜백 함수가 서비스 호출의 쿼리 문자열에 주입되지 않는 것으로 나타났습니다 (jquery-jsonp 버전 2.4.0 현재).

이 질문은 오래되었지만 JSONP를 사용한 오류 처리 문제는 여전히 ‘해결’되지 않았습니다. 이 질문이 Google 내에서 “jquery jsonp 오류 처리”에 대한 최상위 순위이므로이 업데이트가 다른 사용자에게 도움이되기를 바랍니다.


답변

스크립트의 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;
}

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