为了添加一些基本的错误处理,我想重写一段使用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秒后没有成功请求时调用错误处理程序。

我做了一点 blogpost 关于这个问题。

其他提示

这是jQuery中本机jsonp实现的已知限制。以下文字来自 IBM在developerWorks

  

JSONP是一种非常强大的技术   建立mashup,但不幸的是,   这对你们所有人来说都不是万能药   跨域通信需求。它   有一些必须采取的缺点   以前要认真考虑   承诺开发资源。   首先,没有错误   处理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's 答案现在可以在 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错误处理”。

听这个剧本的错误事件怎么样? 我遇到了这个问题并通过修补脚本标记创建的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