首页 文章

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

提问于
浏览
342

在Firefox 3中,每个域的答案是6:只要触发到同一个域的第7个XmlHttpRequest(在任何选项卡上),它就会排队,直到其他6个完成 .

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

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

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

8 回答

  • 24

    对于流行的浏览器,Browserscope的网络结果将为您提供 Connections per HostnameMax Connections . 通过对用户"in the wild,"运行测试来收集数据,以便它保持最新 .

  • 7

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

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

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

  • 101

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

    使用VPN仍然是Clobbers IE 9性能我们之前曾报道过,当您的PC使用VPN连接时,缩小IE 8中的最大并发连接数 . 即使浏览器流量没有超过该连接,也会发生这种情况 . 不幸的是,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>
    

    Edit:
    r表示行和w等待时间 .
    当你最初按下开始按钮80(或任何其他数量)的并发ajax请求是由javascript启动时,但众所周知它们是由浏览器假脱机 . 它们也被并行地请求服务器(限于某个数字,这是这个问题的事实) . 这里请求在服务器端解决,具有随机延迟(由w Build ) . 在开始时,计算解决所有ajax调用所需的所有时间 . 测试完成后,您可以看到它占用了总时间的一半,占了三分之一,花了四分之一等,扣除了对服务器调用的并行性 . 这不是严格的,也不是精确的,但很高兴能够实时看到ajaxs调用是如何完成的(看到传入的交叉) . 并且是一个非常简单的自包含脚本来显示ajax基础知识 .
    当然,这假设服务器端没有引入任何额外限制 .
    最好与萤火虫网面板(或您的浏览器相当)一起使用

  • 3

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

    IE6,IE7 - 限制为2 . 如果你有宽带,IE8是6 - 2(如果它是拨号) .

  • 137

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

    它适用于大多数可以在不同时间触发即时更改事件的网站 . (又名:潮红)

    我注意到我的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,现在最多可以有2x请求

    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();
    });
    
  • 6

    我相信浏览器会对同一个域进行最大数量的并发http请求,这取决于用户的设置和浏览器,大约为4-8个请求 .

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

    我可以问你为什么要这样做很多请求?浏览器限制对同一域的请求数有充分的理由 . 如果可能的话,你最好捆绑请求 .

相关问题