在 Firefox 3 中,答案是每个域 6 个:一旦对同一域的第 7 个 XmlHttpRequest(在任何选项卡上)被触发,它就会排队等待其他 6 个完成。
其他主要浏览器的编号是多少?
此外,是否有办法绕过这些限制,而无需让我的用户修改他们的浏览器设置?例如,jsonp 请求的数量是否有限制(使用脚本标记注入而不是 XmlHttpRequest 对象)?
背景:我的用户可以从网页向服务器发出 XmlHttpRequest,要求服务器在远程主机上运行 ssh 命令。如果远程主机关闭,ssh 命令需要几分钟才能失败,最终阻止我的用户执行任何进一步的命令。
您可以用来增加并发连接数的一个技巧是托管来自不同子域的图像。这些将被视为单独的请求,每个域都将被限制为并发最大值。
IE6、IE7 - 有两个限制。如果您有宽带,则 IE8 为 6 - 2(如果是拨号上网)。
Browserscope 的网络结果将为您提供流行浏览器的 每个主机名的连接数 和 最大连接数。这些数据是通过对“野外”用户进行测试来收集的,因此它会保持最新状态。
使用 IE6 / IE7 可以调整注册表中的并发请求数。以下是如何将其设置为每个四个。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"MaxConnectionsPerServer"=dword:00000004
"MaxConnectionsPer1_0Server"=dword:00000004
without having my users modify their browser settings
。此外,这不切实际,因为必须在每个客户端上执行此操作。
根据 HttpWatch 博客上的 IE 9 – What’s Changed?,IE9 在通过 VPN 时仍然有 2 个连接限制。
使用 VPN 仍然会破坏 IE 9 性能 我们之前曾报道过,当您的 PC 使用 VPN 连接时,IE 8 中的最大并发连接数会缩减。即使浏览器流量没有通过该连接也会发生这种情况。不幸的是,IE 9 以同样的方式受到 VPN 连接的影响:
我已经编写了一个文件 AJAX 测试器。好好享受!!!只是因为我的托管服务提供商有问题
<?php /*
Author: Luis Siquot
Purpose: Check ajax performance and errors
License: GPL
site5: Please don't drop json requests (nor delay)!!!!
*/
$r = (int)$_GET['r'];
$w = (int)$_GET['w'];
if($r) {
sleep($w);
echo json_encode($_GET);
die ();
} //else
?><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
var _settimer;
var _timer;
var _waiting;
$(function(){
clearTable();
$('#boton').bind('click', donow);
})
function donow(){
var w;
var estim = 0;
_waiting = $('#total')[0].value * 1;
clearTable();
for(var r=1;r<=_waiting;r++){
w = Math.floor(Math.random()*6)+2;
estim += w;
dodebug({r:r, w:w});
$.ajax({url: '<?php echo $_SERVER['SCRIPT_NAME']; ?>',
data: {r:r, w:w},
dataType: 'json', // 'html',
type: 'GET',
success: function(CBdata, status) {
CBdebug(CBdata);
}
});
}
doStat(estim);
timer(estim+10);
}
function doStat(what){
$('#stat').replaceWith(
'<table border="0" id="stat"><tr><td>Request Time Sum=<th>'+what+
'<td> /2=<th>'+Math.ceil(what/2)+
'<td> /3=<th>'+Math.ceil(what/3)+
'<td> /4=<th>'+Math.ceil(what/4)+
'<td> /6=<th>'+Math.ceil(what/6)+
'<td> /8=<th>'+Math.ceil(what/8)+
'<td> (seconds)</table>'
);
}
function timer(what){
if(what) {_timer = 0; _settimer = what;}
if(_waiting==0) {
$('#showTimer')[0].innerHTML = 'completed in <b>' + _timer + ' seconds</b> (aprox)';
return ;
}
if(_timer<_settimer){
$('#showTimer')[0].innerHTML = _timer;
setTimeout("timer()",1000);
_timer++;
return;
}
$('#showTimer')[0].innerHTML = '<b>don\'t wait any more!!!</b>';
}
function CBdebug(what){
_waiting--;
$('#req'+what.r)[0].innerHTML = 'x';
}
function dodebug(what){
var tt = '<tr><td>' + what.r + '<td>' + what.w + '<td id=req' + what.r + '> '
$('#debug').append(tt);
}
function clearTable(){
$('#debug').replaceWith('<table border="1" id="debug"><tr><td>Request #<td>Wait Time<td>Done</table>');
}
</script>
</head>
<body>
<center>
<input type="button" value="start" id="boton">
<input type="text" value="80" id="total" size="2"> concurrent json requests
<table id="stat"><tr><td> </table>
Elapsed Time: <span id="showTimer"></span>
<table id="debug"></table>
</center>
</body>
编辑: r 表示行和 w 等待时间。当您最初按下开始按钮时,80 个(或任何其他数量)并发 ajax 请求由 javascript 启动,但众所周知,它们是由浏览器假脱机的。它们也被并行请求到服务器(限于一定数量,这是这个问题的事实)。在这里,请求以随机延迟(由 w 建立)在服务器端解决。在开始时计算解决所有 ajax 调用所需的所有时间。测试完成后,您可以查看总时间的一半、第三、四分之一等,减去对服务器的调用的并行度。这并不严格,也不精确,但很高兴实时查看 ajax 调用是如何完成的(查看传入的交叉)。并且是一个非常简单的自包含脚本来展示 ajax 基础知识。当然,这是假设服务器端没有引入任何额外限制。最好与萤火虫网络面板(或您的浏览器的等价物)结合使用
写了我自己的测试。在stackoverflow上测试了代码,工作正常告诉我chrome/FF可以做6
var change = 0;
var simultanius = 0;
var que = 20; // number of tests
Array(que).join(0).split(0).forEach(function(a,i){
var xhr = new XMLHttpRequest;
xhr.open("GET", "/?"+i); // cacheBust
xhr.onreadystatechange = function() {
if(xhr.readyState == 2){
change++;
simultanius = Math.max(simultanius, change);
}
if(xhr.readyState == 4){
change--;
que--;
if(!que){
console.log(simultanius);
}
}
};
xhr.send();
});
它适用于大多数可以在不同时间触发 readystate 更改事件的网站。 (又名:冲洗)
我注意到在我的 node.js 服务器上我必须输出至少 1025 个字节才能触发事件/刷新。否则,当请求完成时,事件将立即触发所有三种状态,所以这是我的后端:
var app = require('express')();
app.get("/", function(req,res) {
res.write(Array(1025).join("a"));
setTimeout(function() {
res.end("a");
},500);
});
app.listen(80);
更新
我注意到如果您同时使用 xhr 和 fetch api,您现在最多可以有 2 次请求
变量变化 = 0;变量同时= 0;变量 que = 30; // 测试次数 Array(que).join(0).split(0).forEach(function(a,i){ fetch("/?b"+i).then(r => { change++; simultanius = Math.max(simultanius, change); return r.text() }).then(r => { change--; que--; if(!que){ console.log(simultanius); } }); } ); Array(que).join(0).split(0).forEach(function(a,i){ var xhr = new XMLHttpRequest; xhr.open("GET", "/?a"+i); // cacheBust xhr.onreadystatechange = function() { if(xhr.readyState == 2){ change++; simultanius = Math.max(simultanius, change); } if(xhr.readyState == 4){ change--; que--; if(!que){ document.body.innerHTML = simultanius; } } }; xhr.send(); });
我相信浏览器会对同一个域发出最大数量的并发 http 请求,根据用户的设置和浏览器,该请求的顺序为 4-8 个请求。
您可以设置您的请求以转到不同的域,这可能可行,也可能不可行。雅虎人员在这方面进行了大量研究,您可以阅读相关内容 (here)。请记住,您添加的每个新域也需要进行 DNS 查找。 YSlow 建议使用 2 到 4 个域,以在并行请求和 DNS 查找之间取得良好的折衷,尽管这关注的是页面的加载时间,而不是后续的 AJAX 请求。
我能问一下你为什么要提出这么多要求吗?浏览器限制对同一域的请求数量是有充分理由的。如果可能的话,你会更好地捆绑请求。
迁移到 http 2.0 的一个很好的理由
使用 http2.0,每台主机的最大连接数实际上是无限的:Is the per-host connection limit raised with HTTP/2?
不定期副业成功案例分享