【发布时间】:2011-12-02 18:13:45
【问题描述】:
我构建了一个 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 documentation 表示永远不会触发 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 错误。在我的测试用例中,这个处理没有问题,但在我的第二个示例中,错误处理程序似乎从未被调用。
我无法弄清楚为什么测试用例按我预期的那样工作,而第二个却没有。有什么想法吗?
【问题讨论】:
-
尝试升级到 jQuery 1.6.4,结果相同
-
可能是使用 php
header()返回 503 的行为与“实际”503 不同吗?我检查了这两种情况的 HTTP 标头,它们看起来和我一模一样... -
在您的第一个示例中,您在错误处理程序中每次 (x++;) 递增 x。在您的第二个中,您不会增加 index++;这是我能看到的唯一明显区别。
-
另外,您是否尝试过不使用 die() 命令的 503 测试?这是否会阻止添加其他服务器标头,从而导致它在第二种情况下利用成功?
-
另外,你的标题调用不应该是这样的吗? header("HTTP/1.0 503 服务暂时不可用", true, 503);也许这导致他们的行为不同?更多想法请看这里:stackoverflow.com/questions/2760884/…(好吧,我现在去:))
标签: jquery ajax error-handling cross-domain jsonp