【问题标题】:How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?流行的浏览器允许多少并发 AJAX (XmlHttpRequest) 请求?
【发布时间】:2010-10-08 08:15:42
【问题描述】:

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

其他主要浏览器的数字是多少?

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

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

【问题讨论】:

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

标签: ajax browser xmlhttprequest


【解决方案1】:

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

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

【讨论】:

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

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

【讨论】:

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

使用 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。此外,这不切实际,因为必须在每个客户端上都这样做。
  • 这仍然是与此问题相关的非常有用的知识。也许它会更好地发布在评论中而不是作为答案?
【解决方案4】:

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

【讨论】:

    【解决方案5】:

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

    使用 VPN 仍然会破坏 IE 9 性能

    我们之前曾报道过 关于最大值的缩减 IE中的并发连接数 8 当您的 PC 使用 VPN 连接时。 即使浏览器也会发生这种情况 流量没有超过那个 连接。

    很遗憾,IE 9 受 VPN 影响 以同样的方式连接:

    【讨论】:

      【解决方案6】:

      我已经编写了一个单文件 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 基础知识。
      当然,这是假设服务器端没有引入任何额外限制。
      最好与 firebug 网络面板(或您的浏览器的等效面板)结合使用

      【讨论】:

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

      写了我自己的测试。在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 次请求

      var change = 0;
      var simultanius = 0;
      var que = 30; // number of tests
      
      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。
      【解决方案8】:

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

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

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

      【讨论】:

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

      迁移到 http 2.0 的好理由

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

      【讨论】:

        猜你喜欢
        • 2011-10-30
        • 2017-03-07
        • 2011-05-04
        • 2015-03-28
        • 2020-04-23
        • 2011-10-28
        • 1970-01-01
        相关资源
        最近更新 更多