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

时间:2009-02-18 13:28:16

标签: ajax browser xmlhttprequest

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

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

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

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

8 个答案:

答案 0 :(得分:138)

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

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

答案 1 :(得分:102)

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

答案 2 :(得分:24)

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

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

答案 3 :(得分:7)

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

答案 4 :(得分: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调用所需的所有时间。测试完成后,您可以看到它占用了总时间的一半,占了三分之一,花了四分之一等,扣除了对服务器调用的并行性。这不是严格的,也不是精确的,但很高兴能够实时看到ajaxs调用是如何完成的(看到传入的交叉)。并且是一个非常简单的自包含脚本来显示ajax基础知识 当然,这假设服务器端没有引入任何额外限制 最好与萤火虫网面板(或您的浏览器等效)一起使用

答案 5 :(得分:6)

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

  

使用VPN仍然是Clobbers IE 9性能

     

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

     

不幸的是,IE 9受到VPN的影响   连接方式相同:

答案 6 :(得分:4)

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

答案 7 :(得分:0)

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

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

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