浏览器何时会将 HTTP 有效负载与 HTTP 请求分开发送?

浏览器何时会将 HTTP 有效负载与 HTTP 请求分开发送?

在什么情况下,你会期望 Web 浏览器将 HTTP 请求拆分为两个 IP 数据包,即使数据包大小的总和仍小于最大段大小?我认为这将始终作为单个数据包发送,但我的经验表明并非如此。

使用 Microsoft Network Monitor 分析 HTTP 流量时,偶尔会看到一个请求被分成两个 IP 数据包,如下所示

HTTP:Request, POST /foobar.htm (PacketID=55178, TotalLength=528)
  POST /foobar.htm HTTP/1.1
  Content-Type: application/x-www-form-urlencoded
  ...etc...

HTTP:HTTP Payload, URL: /foo.htm (PacketID=55179, TotalLength=98)
  param1=foo&param2=bar&param3=foo+bar

到目前为止,我只在 Windows XP 客户端上看到这种情况,但并非所有 XP 客户端都会发生这种情况。在受影响的系统上,IE8 和 Firefox 都表现出相同的双包行为。


背景:我们最近开始使用第三方软件包,该软件包在我们的内部网上提供 Web 应用程序。但该软件不使用 IIS 或 Apache 等真正的 Web 服务器,而是在内部实现自己的 HTTP 服务器。

由于服务器使用简单的 HTTP 实现,它仅检查 HTTP 请求的第一个数据包,而忽略了第二个数据包中发送的参数。这会导致请求失败。

答案1

它是随机的和不可预测的,如果你在意它,那你就做错了什么。

由于服务器使用简单的 HTTP 实现,它仅检查 HTTP 请求的第一个数据包,而忽略了第二个数据包中发送的参数。这会导致请求失败。

我不明白你到底想说什么。如果它实际上在查看数据包,那么它是 TCP 的实现,而不是 HTTP(因为根据 TCP 规范,数据包是数据包)。合理的 HTTP 实现永远不会查看数据包。

如果您的意思是 HTTP 服务器查看数据包,那么它必须重建 TCP 数据流,然后遵循 HTTP 协议。HTTP 请求的结尾在 TCP 字节流中用两个 <CRLF> 标记。任何其他检测 HTTP 请求结尾的方法都是无效的。

由于第一个数据包不包含 HTTP 请求结束序列,因此它显然不能包含整个请求。

HTTP 服务器必须遵循 HTTP 规范,否则它就不是 HTTP 服务器。HTTP 规范仅指定了哪些字节进入 TCP 数据流。它没有提到分段,这很好,因为实际上应用程序无法控制分段。它指定了如何识别请求的结束,不符合该规范的代码不是HTTP 服务器。它实现了类似 HTTP 的协议,但可能与 HTTP 兼容,也可能不兼容。

答案2

有问题的 POST 是如何生成的 - 是通过 XMLHTTPRequest 即 AJAX 生成的吗?

AJAX POST 将标头和正文作为至少两个单独的 TCP 数据包发送。

几年前,雅虎开发者网络上有一篇关于此问题的博客文章。

相关内容