处理跨域 jsonp 调用的 jQuery.ajax 错误
我构建了一个 ajax 调用(jQuery 1.6.2)的测试用例,如下所示:
jQuery( document ).ready( function( $ ) {
var test = function( x ) {
$.ajax({
url: 'http://www.someotherdomain.com/test.php',
data: { x: x },
dataType: 'jsonp',
crossDomain: true,
success: function( data ) {
console.log( data.name );
},
error: function() {
x++;
test( x );
}
});
};
test( 1 );
});
相应的 test.php 文件如下所示:
if ( 5 > $_GET[ 'x' ] ) {
header('HTTP/1.1 503 Service Temporarily Unavailable'); die();
} else {
header( 'content-type: application/x-javascript' );
echo $_GET[ 'callback' ] . '({"name":"Morgan"})';
}
即使 jQuery 文档 表明 jsonp 调用的错误处理程序永远不会被触发,该脚本按照我的预期工作。它对 test.php 进行了四次“不成功”调用,返回 503 错误,然后 test() 递归调用自身并递增 x,直到 ajax 调用“成功”并将数据输出到控制台。
所以我上面的测试用例有效,但我的实际代码不起作用,它看起来更像是以下内容:
jQuery( document ).ready( function( $ ) {
var completed = 0;
var fiftystates; // assume an array of state objects
var updateState = function( index, state ) {
var d = index % 5; // for subdomains sub0, sub1, sub2, sub3, sub4
$.ajax({
url: 'http://sub' + d + '.mydomain.com/update_state.php',
data: { state: state.id },
dataType: 'jsonp',
crossDomain: true,
success: function() {
completed++;
var complete_percent = completed / fiftystates.length * 100;
$( '#progressbar' ).progressbar( 'value', completed_percent );
},
error: function() {
updateState( index, state );
}
}); // end ajax
}; // end updateState
$( fiftystates ).each( updateState );
};
如您所见,这循环通过 5 个不同的子域,这些子域实际上只是同一域的镜像,但自 update_state. php 最多可能需要 30 秒才能完成,这需要 25 分钟的过程减少到不到三分钟。问题是服务器崩溃导致某些 ajax 请求失败并出现 503 错误。在我的测试用例中,处理没有问题,但在我的第二个示例中,错误处理程序似乎从未被调用。
我不明白为什么测试用例按我的预期工作,而第二个测试用例却没有。有什么想法吗?
I built a test case of an ajax call (jQuery 1.6.2) that looks like:
jQuery( document ).ready( function( $ ) {
var test = function( x ) {
$.ajax({
url: 'http://www.someotherdomain.com/test.php',
data: { x: x },
dataType: 'jsonp',
crossDomain: true,
success: function( data ) {
console.log( data.name );
},
error: function() {
x++;
test( x );
}
});
};
test( 1 );
});
And the corresponding test.php file looks like:
if ( 5 > $_GET[ 'x' ] ) {
header('HTTP/1.1 503 Service Temporarily Unavailable'); die();
} else {
header( 'content-type: application/x-javascript' );
echo $_GET[ 'callback' ] . '({"name":"Morgan"})';
}
Even though the jQuery documentation indicates that the error handler for jsonp calls is never fired, this script works just as I intended. It makes four "unsuccessful" calls to test.php which return 503 errors, and then test()
recursively calls itself incrementing x until the ajax call is "successful" and the data is output to the console.
So my test case above works, but my actual code doesn't work, which looks more like the following:
jQuery( document ).ready( function( $ ) {
var completed = 0;
var fiftystates; // assume an array of state objects
var updateState = function( index, state ) {
var d = index % 5; // for subdomains sub0, sub1, sub2, sub3, sub4
$.ajax({
url: 'http://sub' + d + '.mydomain.com/update_state.php',
data: { state: state.id },
dataType: 'jsonp',
crossDomain: true,
success: function() {
completed++;
var complete_percent = completed / fiftystates.length * 100;
$( '#progressbar' ).progressbar( 'value', completed_percent );
},
error: function() {
updateState( index, state );
}
}); // end ajax
}; // end updateState
$( fiftystates ).each( updateState );
};
As you can see, this loops through 5 different sub-domains which are actually just mirrors of the same domain, but since update_state.php can take up to 30 seconds to complete, this takes a 25 minute process down to less than three minutes. The problem is that the server pounding causes some of the ajax requests to fail with a 503 error. In my test case this was handled with no problem but in my second example, the error handler never seems to get called.
I can't figure out why the test case works as I expect and the second one doesn't. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
应该是这样的格式:
should it be in format like this:
在您的测试用例中,您每次调用都会更改值x...
在其他代码中,您发送相同的索引值。这将返回相同的结果,而不是通过子域“循环”......
In your test case you change teh value x für each call...
In the other code you're sending the same index value. Which will return the same result, instead of "revolving" through the subdomains...
如果您碰巧使用 IE 来测试第一种情况,并且可能使用 FF 或 Chrome 来测试第二种情况,那么这可能就是原因。如 jQuery.ajax 函数所述,跨域 JSON/JSONP 类型不会调用错误和全局回调。但是,我注意到它们仍然在 IE 中被调用,我认为这与 jQuery 使用 IE XMLHttpRequest 进行调用有关。
看来有人慷慨地创建了一个插件,可以处理此处提供的 JSONP 请求的错误:http://code .google.com/p/jquery-jsonp/
If by chance you were using IE to test the first case and possibly FF or Chrome to test the second case then that may be the cause. Error and Global callbacks are not called for cross domain JSON/JSONP types as documented by the jQuery.ajax function. However, I have noticed that they do still get called in IE and I think this has something to do with jQuery using the IE XMLHttpRequest to do the calls.
It appears someone has graciously created a plugin that handles errors with JSONP requests available here: http://code.google.com/p/jquery-jsonp/