for (var i = 0; i < 5; ++i) {
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
}
xhr.open('GET', '/Test/LongOperation?p=' + new Date());
xhr.send('');
}
这只是一个演示(不是实时代码),但它说明了核心问题。
LongOperation
是一种在10秒后返回结果的方法。
问题:
当上述代码片段执行完毕后,当用户试图离开页面时,为什么IE8(以及其他IE)会挂起? FireFox / Safari取消这些请求并允许导航到另一个页面。如果您将'i < 5'
替换为'i < 4'
,那么IE就不会挂起。
如何解决这种丑陋的IE行为?当浏览器突然挂起时,用户非常沮丧。
答案 0 :(得分:3)
大多数浏览器都内置了4个连接到任何给定服务器的限制。解决此“问题”的一种方法可能是为带外XML请求使用不同的主机名 - 您的用户请求将转到主要主机,而AJAX请求可以转到第二个服务器。
答案 1 :(得分:2)
我对我的问题的回答。我在window.onbeforeunload中中止所有未完成的xhr对象。至少这个解决方案适合我。我略微覆盖$ .ajax()方法行为:
;(function($) {
var rq = [];
var ajax = $.ajax;
$.ajax = function(settings) {
// override complete() operation
var complete = settings.complete;
settings.complete = function(xhr) {
if (xhr) {
// xhr may be undefined, for example when downloading JavaScript
for (var i = 0, len = rq.length; i < len; ++i) {
if (rq[i] == xhr) {
// drop completed xhr from list
rq.splice(i, 1);
break;
}
}
}
// execute base
if (complete) {
complete.apply(this, arguments)
}
}
var r = ajax.apply(this, arguments);
if (r) {
// r may be undefined, for example when downloading JavaScript
rq.push(r);
}
return r;
};
// 'kill' all pending xhrs
$(window).bind('beforeunload', function() {
$.each(rq, function(i, xhr) {
try {
xhr.abort();
} catch(e) {
$debug.fail('failed to abort xhr');
}
});
rq = [];
});
})(jQuery);
$ debug - 我的实用程序类
答案 2 :(得分:0)
尝试异步运行它们,然后在每个http请求完成时触发下一个http请求。我怀疑xmlhttp请求阻止了IE的UI线程,而其他浏览器上的实现更优雅。
希望这会让你解决问题2,但我只能猜测问题1的真正原因,它可能只是一个错误。