HTTP 头部对于浏览器来说有大小限制吗?

18
我正在构建一个AJAX应用程序,使用HTTP内容和HTTP头发送和接收数据。是否存在从HTTP头接收的数据太大而无法被浏览器读取的点?如果是,限制是什么,所有浏览器的行为都相同吗?
我知道理论上HTTP头的大小没有限制,但在实践中,过了某个点后,我可能会在某些平台、浏览器或客户端计算机或机器上安装某些软件时遇到问题。我更希望得到使用HTTP头的安全实践指南。换句话说,可以在没有潜在问题的情况下使用HTTP头来传输其他数据的范围有多大?

感谢您对这个问题的所有输入,非常感激和有趣。托马斯的答案得到了悬赏,但是乔恩·汉纳的答案提出了一个关于代理的很好的观点。


1
你通过头部传输什么样的数据?如果你使用 AJAX,为什么不使用 JSON 或 XML 而不是将内容放入头部? - iblamefish
正如问题所述,我已经在使用结果的内容作为数据。头部传递的数据是额外的数据。对于发送的数据,它是JSON编码的数据。 - HoLyVieR
是否存在实际的HTTP头长度限制? - ankitjaininfo
正如唯一答案中所述,我正在寻找浏览器可以接受的内容,而不是服务器。这不是我要找的。 - HoLyVieR
1
关于您的声明“如问题所述,我已经使用结果内容作为数据。在头部传递的数据是额外的数据。”为什么您要传输的数据不能放在它应该放置的位置(即正文中)?您添加了哪些额外的头部信息? - Hut8
显示剩余11条评论
5个回答

46

简短回答:

行为是否相同:否

主流浏览器中找到的最低限制:

  • 每个头部10KB
  • 一次响应中所有头部的总大小为256 KB。

在运行 Mac OS X 10.6.4 的 MacBook 上测试结果:

成功加载的最大响应,所有数据都在一个头部中:

  • Opera 10: 150MB
  • Safari 5: 20MB
  • 经 Wine 运行的 IE 6: 10MB
  • Chrome 5: 250KB
  • Firefox 3.6: 10KB

注意: 在 Opera、Safari 和 IE 中出现过于庞大的头部会花费几分钟的时间来加载。

注意 Chrome: 实际限制似乎是整个 HTTP 头部的256KB。 错误消息显示:"Error 325 (net::ERR_RESPONSE_HEADERS_TOO_BIG): Unknown error."

注意 Firefox: 通过多个头部发送数据时,100MB 的数据能够正常工作,只需分成10,000个头部即可。

我的结论: 如果您想要支持所有主流浏览器,则每个头部的大小限制为10KB,而所有头部的总大小限制为256KB。

生成这些响应的 PHP 代码:

<?php

ini_set('memory_limit', '1024M');
set_time_limit(90);
$header = "";

$bytes = 256000;

for($i=0;$i<$bytes;$i++) {
    $header .= "1";
}

header("MyData: ".$header);
/* Firfox multiple headers
for($i=1;$i<1000;$i++) {
    header("MyData".$i.": ".$header);
}*/

echo "Length of header: ".($bytes / 1024).' kilobytes';

?>

更新后的数值: Firefox 99:每个头部略低于393,216 B。 Chrome 100:每个头部250 KB。 - ZachB

8
实际上,虽然有规则禁止代理不传递某些标头(确实,对于哪些标头可以被修改甚至如何通知代理它是否可以修改后来的标头,有非常明确的规定),但这仅适用于“透明”代理,并非所有代理都是透明的。特别是,一些代理会删除它们不理解的标头,作为一种故意的安全措施。
此外,在实践中,有些代理确实会表现不当(尽管情况比以前好多了)。
因此,除了显而易见的核心标头外,您可以依赖从服务器传递到客户端的标头信息量为零。
这只是您永远不应该依赖标头使用良好的原因之一(例如,准备好让客户端重复请求其应该缓存的内容,或者让服务器在您请求范围时发送整个实体),除了身份验证标头的明显情况(根据失败保护原则)。

4

两件事。

首先,为什么不运行一个测试,逐渐增加浏览器的头部大小,并等待它达到无法工作的数字?只需在每个浏览器上运行一次。这是找出答案最可靠的方法。即使它并不完全全面,你至少有一些实际的数字可以参考,而这些数字很可能涵盖了绝大多数用户。

其次,我同意所有说这是个坏主意的人。如果你真的很担心达到限制,应该不难找到其他解决方案。即使你在每个浏览器上都进行了测试,仍然需要担心防火墙等问题,而且几乎没有人能够测试每种组合(我几乎可以肯定在你之前没有人这样做过)。你将无法为每种情况得到硬性限制。

尽管在理论上,这一切都应该很好地解决,但如果你决定这样做,可能会有那么一个边缘情况会让你后悔。

简而言之:这是个坏主意。 不要给自己找麻烦,找一个真正的解决方案,而不是一个变通方法。


编辑:由于你提到请求可能来自多种类型的来源,为什么不只在请求头中指定来源,并将数据完全包含在正文中呢?在头部中添加某种SourceClientType字段,指定请求来自何处。如果是来自浏览器,请在正文中包含HTML;如果来自PHP应用程序,请在其中放置一些特定于PHP的内容;等等。如果该字段为空,则根本不添加任何额外数据。


1
+1 如果提供源或客户端类型。您可以使用GET参数来指定应给出何种响应。 - Michael Aaron Safyan

2
HTTP/1.1的RFC明确没有限制标头或正文的长度。现代浏览器(Firefox,Safari和Opera)可以处理非常长的URI,但IE除外,详情请参见此页面:https://web.archive.org/web/20191019132547/https://boutell.com/newfaq/misc/urllength.html。虽然这与接收标头不同,但至少表明它们可以创建和发送巨大的HTTP请求(可能是无限长度)。如果浏览器有任何限制,那么它可能是可用内存大小或变量类型限制等。请注意保留HTML标签。

1
对于所有点赞此回答的人,请注意,它仅阐述了协议规定的内容,理论上浏览器应该如何处理,但正如大家所知,理论往往与实践不同。这不是我要找的答案,只是一种关于答案可能是什么的感觉。我需要更多的东西,而不仅仅是“我有一种感觉,可能是这样”。 - HoLyVieR
1
我同意HoLyVieR的观点,这并不是一个真正的答案,只是一些相关信息。实际上,这本来就不是一个很好的问题,因为它要求的统计数据通常并没有被公开发布,因为人们通常并不关心。然而,对于那些真的很在意的人来说,编写一个测试浏览器极限的AJAX应用程序,然后在各种浏览器中运行它有多难呢?这样得出的结果比询问其他人谁没有进行过这样的测试更可靠。 - Samuel Neff

1
理论上,浏览器发送数据的数量是没有限制的。这就好像说网页正文中的内容有限制一样。
如果可能的话,尽量通过文档正文传输数据。为了安全起见,考虑将数据分割成多个部分进行加载。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接