为了添加一些基本的错误处理,我想重写一段代码,该代码使用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;
}
您如何看待该解决方案?有可能引起兼容性问题吗?
文章标签:ajax , error-handling , jquery , jsonp , timeout
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!
评论已关闭!