ChatGPT解决这个技术问题 Extra ChatGPT

流行的浏览器允许多少并发 AJAX (XmlHttpRequest) 请求?

在 Firefox 3 中,答案是每个域 6 个:一旦对同一域的第 7 个 XmlHttpRequest(在任何选项卡上)被触发,它就会排队等待其他 6 个完成。

其他主要浏览器的编号是多少?

此外,是否有办法绕过这些限制,而无需让我的用户修改他们的浏览器设置?例如,jsonp 请求的数量是否有限制(使用脚本标记注入而不是 XmlHttpRequest 对象)?

背景:我的用户可以从网页向服务器发出 XmlHttpRequest,要求服务器在远程主机上运行 ssh 命令。如果远程主机关闭,ssh 命令需要几分钟才能失败,最终阻止我的用户执行任何进一步的命令。

想想你的情况,ping远程软管看它是向上还是向下的可行性是什么?这不会回答您的问题,但这可能是一个更好的工作流程。
谢谢鲍勃,这是我计划解决这个问题的两种方法之一——我考虑在问题中提到它,但认为它是题外话。 (另一种方法是让我控制的服务器超时 ssh 请求。)
我认为你几乎有你的答案......假设 Safari 和 Chrome 至少支持 2 是非常安全的,所以你总是可以假设 2。
在 Windows Vista 上使用 Chrome 2.0.172.28 我得到了 6 个并发连接。
我刚刚发现这个页面 stevesouders.com/blog/2008/03/20/…,它提供了更多的数字和对此的讨论。

C
CrownedClown

您可以用来增加并发连接数的一个技巧是托管来自不同子域的图像。这些将被视为单独的请求,每个域都将被限制为并发最大值。

IE6、IE7 - 有两个限制。如果您有宽带,则 IE8 为 6 - 2(如果是拨号上网)。


不,限制是对域施加的。因此,如果您在站点之外还有一个子域,那么从技术上讲,您可以获得多达 12 个 FF 连接。
因此,如果我理解您的话,FF 将所有请求(对单个域)限制为 6 个——而不仅仅是对单个域的 XmlHttpRequests。其他浏览器做同样的事情有不同的限制。正确的?
哦,是的,如果您有一个包含一千张图片的页面,它将以六张为一组下载它们。我相信大多数其他主流浏览器都以相同的方式工作。
哇。这是一个很好的技巧。这也解释了为什么地图引擎的瓦片服务器会创建许多虚假的子域(通常像 maps1.whatever.com、maps2.whatever.com、maps3.whatever.com 之类的东西)来加速事情。
@AMember,浏览器始终保持并行的最大并发ajax数量。如果您想看到实际效果,请在下面尝试我的答案
K
Kevin Hakanson

Browserscope 的网络结果将为您提供流行浏览器的 每个主机名的连接数最大连接数。这些数据是通过对“野外”用户进行测试来收集的,因此它会保持最新状态。


不幸的是,这看起来不是最新的
@DaveLawrence 我刚刚检查过,完整的数据集似乎包含最新的 Chrome 60 和 61。
任何人都有浏览器范围的替代品来测试这个,看起来工具不再托管。
b
brianegge

使用 IE6 / IE7 可以调整注册表中的并发请求数。以下是如何将其设置为每个四个。

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"MaxConnectionsPerServer"=dword:00000004
"MaxConnectionsPer1_0Server"=dword:00000004

-1。 OP 说without having my users modify their browser settings。此外,这不切实际,因为必须在每个客户端上执行此操作。
尽管如此,与此问题相关,这仍然是一件非常有用的事情。也许它会更好地发布在评论中而不是作为答案?
L
LeftyX

我刚刚检查了 www.browserscope.org,使用 IE9 和 Chrome 24,您可以有 6 个并发连接到单个域,最多可以有 17 个并发连接到多个域。


K
Kevin Hakanson

根据 HttpWatch 博客上的 IE 9 – What’s Changed?,IE9 在通过 VPN 时仍然有 2 个连接限制。

使用 VPN 仍然会破坏 IE 9 性能 我们之前曾报道过,当您的 PC 使用 VPN 连接时,IE 8 中的最大并发连接数会缩减。即使浏览器流量没有通过该连接也会发生这种情况。不幸的是,IE 9 以同样的方式受到 VPN 连接的影响:


L
Luis Siquot

我已经编写了一个文件 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>&nbsp;&nbsp;/2=<th>'+Math.ceil(what/2)+
       '<td>&nbsp;&nbsp;/3=<th>'+Math.ceil(what/3)+
       '<td>&nbsp;&nbsp;/4=<th>'+Math.ceil(what/4)+
       '<td>&nbsp;&nbsp;/6=<th>'+Math.ceil(what/6)+
       '<td>&nbsp;&nbsp;/8=<th>'+Math.ceil(what/8)+
       '<td> &nbsp; (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 + '>&nbsp;'
    $('#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>&nbsp;</table>
Elapsed Time: <span id="showTimer"></span>
<table id="debug"></table>
</center>
</body>

编辑: r 表示行和 w 等待时间。当您最初按下开始按钮时,80 个(或任何其他数量)并发 ajax 请求由 javascript 启动,但众所周知,它们是由浏览器假脱机的。它们也被并行请求到服务器(限于一定数量,这是这个问题的事实)。在这里,请求以随机延迟(由 w 建立)在服务器端解决。在开始时计算解决所有 ajax 调用所需的所有时间。测试完成后,您可以查看总时间的一半、第三、四分之一等,减去对服务器的调用的并行度。这并不严格,也不精确,但很高兴实时查看 ajax 调用是如何完成的(查看传入的交叉)。并且是一个非常简单的自包含脚本来展示 ajax 基础知识。当然,这是假设服务器端没有引入任何额外限制。最好与萤火虫网络面板(或您的浏览器的等价物)结合使用


所以我确认,FF3 最多启动六个并发请求
你能解释一下你在这里做了什么吗?什么是 r 和 w ?分析结果的打印屏幕将不胜感激
E
Endless

写了我自己的测试。在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(); });


我的上面写着19,是不是坏了?
Firefox 开发者版 57.0b12 说 2。
c
cbp

我相信浏览器会对同一个域发出最大数量的并发 http 请求,根据用户的设置和浏览器,该请求的顺序为 4-8 个请求。

您可以设置您的请求以转到不同的域,这可能可行,也可能不可行。雅虎人员在这方面进行了大量研究,您可以阅读相关内容 (here)。请记住,您添加的每个新域也需要进行 DNS 查找。 YSlow 建议使用 2 到 4 个域,以在并行请求和 DNS 查找之间取得良好的折衷,尽管这关注的是页面的加载时间,而不是后续的 AJAX 请求。

我能问一下你为什么要提出这么多要求吗?浏览器限制对同一域的请求数量是有充分理由的。如果可能的话,你会更好地捆绑请求。


由于同源策略,我的 XmlHttpRequests 无法按照您的建议转到不同的域。 (也许这是使用 jsonp 来解决这个问题的一个论据。)这个页面是许多计算机的命令和控制仪表板;因此,每次用户请求的执行都会产生一个请求。
R
Raskolnikov

迁移到 http 2.0 的一个很好的理由

使用 http2.0,每台主机的最大连接数实际上是无限的:Is the per-host connection limit raised with HTTP/2?


HTTP2 上的 abt ajax 请求是什么?浏览器目前不支持该功能。
@RamPrakash 那不是真的。您可以在 Chrome 的网络选项卡上看到一个 h2 协议...显示 http2 连接
那是针对静态文件的。不适用于 ajax 请求。你能给我一个你看到的链接吗?到目前为止,这是浏览器的限制。