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


358

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

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

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

背景:我的用户可以从网页向服务器发出XmlHttpRequest,要求服务器在远程主机上运行ssh命令。如果远程主机关闭,则ssh命令需要几分钟的时间才能失败,最终使我的用户无法执行任何其他命令。


考虑到您的情况,对远程软管执行ping操作以查看其状态是可行还是可行的?这不会回答您的问题,但这可能是更好的工作流程。
鲍勃,

1
谢谢鲍勃,这是我计划解决此问题的两种方法之一-我考虑在问题中提及它,但认为它是题外话。(另一种方法是让我控制的服务器超时ssh请求。)
Michael Gundlach

1
我觉得你非常有你的答案......这是超过安全的假设,Safari和Chrome支持至少2个,这样你就可以总是假设2
雷克斯中号

1
在Windows Vista上使用Chrome 2.0.172.28,我获得了6个并发连接。
卡鲁姆

2
我刚刚找到此页面stevesouders.com/blog/2008/03/20/…,其中提供了更多数字并对此进行了讨论。
大卫·约翰斯通

Answers:


143

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

IE6,IE7-不得超过两个。如果您有宽带,则IE8为6-如果是宽带则为2。


4
不,限制是强加在域上的。因此,如果您除站点外还拥有子域,从技术上讲,您最多可以获取12个连接的FF。
鲍勃,

1
因此,据我了解,FF将所有请求(到单个域)限制为6个,而不仅仅是XmlHttpRequests到单个域。其他浏览器在做相同的事情时有不同的限制。正确?
Michael Gundlach,

1
哦,是的,如果您的页面上有一千张图片,它将以六个为一组下载它们。我相信大多数其他主流浏览器都以相同的方式工作。
鲍勃(Bob)

7
哇。这是一个好把戏。这也解释了为什么地图引擎的图块服务器会创建许多伪造的子域(通常是诸如maps1.whatever.com,maps2.whatever.com,maps3.whatever.com之类的东西)来加速操作。
meawoppl

2
@AMember,浏览器始终保持并行允许的最大并发ajax数量。如果您想查看实际情况,请尝试以下我的答案
Luis Siquot 2014年

103

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


3
不幸的是,这看起来并不是最新的消息
Dave Lawrence

我刚刚检查了@DaveLawrence,整个数据集似乎包含了最新的Chrome 60和61。
西蒙·伊斯特

24

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

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

15
-1。OP说without having my users modify their browser settings。而且,这是不切实际的,因为每个客户都必须这样做。
Razort4x

23
尽管如此,这是与该问题相关的非常有用的事情。也许最好将其发布在评论中而不是作为答案?
JD Smith,

7

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


6

根据IE 9 –发生了什么变化?在HttpWatch博客上,通过VPN时IE9仍然有2个连接限制。

使用VPN Still 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>

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


所以我确认FF3最多发起六个并发请求
Luis Siquot 2011年

你能解释一下你在这里做什么吗?什么是r和w?分析结果的印刷屏幕将不胜感激
Royi Namir

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


它在我上面说19,它坏了吗?
PauAI

Firefox开发人员版本57.0b12说
2。– AnthonyB

0

我相信浏览器将向同一域发出的并发http请求数量上限,根据用户的设置和浏览器,该请求的数量大约为4-8个。

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

请问您为什么要提出这么多请求?浏览器有充分的理由将请求数量限制到同一域。如果可能的话,最好将请求捆绑在一起。


1
由于相同的原产地政策,我的XmlHttpRequests无法进入您建议的不同域。(也许这是使用jsonp来解决此问题的一个论据。)此页面是许多计算机的命令和控制仪表板。因此,每次用户执行请求都会产生一个请求。
Michael Gundlach,2009年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.