是否有任何浏览器支持以分块编码响应发送的预告片?

Posted

技术标签:

【中文标题】是否有任何浏览器支持以分块编码响应发送的预告片?【英文标题】:Do any browsers support trailers sent in chunked encoding responses? 【发布时间】:2012-11-02 12:13:00 【问题描述】:

HTTP/1.1 指定作为Transfer-Encoding: chunked 发送的响应可以包含可选的尾部(即通常作为头部发送的内容,但由于某种原因不能在内容之前计算,因此它们可以附加到结束),例如:

请求:

GET /trailers.html HTTP/1.1
TE: chunked, trailers

回应:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Trailer: My-Test-Trailer
D\r\n
All your base\r\n
B\r\n;
 are belong\r\n
6\r\n
 to us\r\n
0\r\n
My-Test-Trailer: something\r\n
\r\n

此请求在TE 标头中指定它期待chunked 响应,并将在最后一个块之后寻找trailers

响应在 Trailer 标头中指定它将发送的预告片列表(在这种情况下,只有一个:My-Test-Trailer

每个块都被发送为:

以十六进制表示的块大小 (D = 13),后跟 CRLF 块数据(All your base),后跟CRLF

零大小的块 (0\r\n) 表示正文结束。

然后指定预告片 (My-Test-Trailer: something\r\n),最后是 CRLF

现在,从我目前阅读的所有内容来看,预告片很少(如果有的话)使用。大多数here 和其他地方关于预告片的讨论通常以“但你为什么还要使用预告片?”开头。

暂且不说为什么,出于好奇,我一直在尝试模拟使用预告片的 HTTP 请求/响应交换;但到目前为止,我还不能让它工作,我不确定我生成的响应是否有问题,或者(正如一些人建议的那样)根本没有客户端在寻找尾随标头.

我尝试过的客户端包括:curl、wfetch、Chrome + jQuery。

在所有情况下,客户端都会接收并正确重建分块响应 (All your base are belong to us);我可以在响应标头中看到 Trailer: My-Test-Trailer 正在发送;但我没有看到My-Test-Trailier: something 在响应标头或任何地方返回。 在收到整个响应并关闭连接后,不清楚这样的尾随标头是否应该作为正常的响应标头出现在客户端中?

有趣的是,curl change logs 似乎暗示 curl 确实支持可选的预告片,并且 curl 将处理它找到的任何预告片 into the normal header stream。

有人知道吗:

我可以 ping 的有效 URL,它在分块响应中发送预告片? (以便我可以确认是否只是我的测试响应不起作用);和 已知哪些客户端支持(并访问/显示)服务器发送的预告片?

【问题讨论】:

也许“做任何浏览器......”这个问题具有误导性;正如我注意到的那样,类似的问题已由用 Java 实现自己的自定义 HTTP 服务器的人 (***.com/questions/7851645/…) 解决。因此,问题可能应该是“是否有任何服务器支持以分块编码响应发送的预告片?”。 作为 HTTP 标准的一部分,所有声称支持分块传输的浏览器都应该支持它,当然。那么你的代码有问题吗?是什么让您认为浏览器有问题? Raedwald:正如您从我之前的评论中看到的那样,我不一定认为浏览器有问题......这可能是服务器端问题。这当然可能是我的代码的问题(我不怀疑),这就是为什么我要求提供一个正确发送预告片的示例 URL,这将确认问题是否是我的测试。 Scala 的喷雾确实可以正确发送预告片 - 但除了 telnet 我还没有找到任何支持它们的客户端。根据我的测试,curl 和 Charles 都没有。 【参考方案1】:

没有常见的浏览器支持 HTTP/1.1 预告片。查看browserscope的“网络”标签中的“预告片中的标题”列。

Chrome:不,不会修复 (bug)。支持 H/2 拖车 (bug)。 Firefox:没有,我在 bugzilla 中没有看到它的票证。似乎支持 H/2。 IE:否 边缘:否 Safari:否 Opera:仅限旧版本(v10 - 12,在 14 中删除)

如您所见,许多非浏览器客户端都支持它。

【讨论】:

【参考方案2】:

问这个问题已经 5 年多了,现在我可以自己明确地回答了。

Mozilla 刚刚宣布,他们将支持新的 Server-Timing 字段作为 HTTP 尾随标头(他们首次支持尾随标头)。

https://bugzilla.mozilla.org/show_bug.cgi?id=1413999

但是,更重要的是,他们确认它将被列入白名单,因此 Server-Timing 是唯一的支持值(强调我的):

Server-Timing 是 HTTP 预告片,而不是标头。 :mcmanus 告诉我 我们目前正在解析预告片,然后默默地将它们扔掉。我们一般不想改变这种行为(我们不想鼓励预告片),所以我们希望将 Server-Timing 预告片列入白名单,将其存储在某个地方(甚至可能只是一个 mServerTiming 标头现在工作,因为它是我们支持的唯一预告片),然后通过一些新的 channel.getTrailers() 调用使其可用。

所以我想这可以一劳永逸地证实:Moz 不支持尾随标头(并且永远不可能是一般意义上的),并且可能所有其他浏览器供应商都采取相同的立场。

【讨论】:

看起来浏览器最近才开始支持这一点 - 请参阅 caniuse.com/#search=trailer 和 the referenced MDN docs。让我想知道为什么,以及与 HTTP2 功能的关系...【参考方案3】:

由于this commit,Jodd HTTP Java client 支持预告片头。

关于第一个问题,我还没有找到任何使用它们的实时响应;)

【讨论】:

我也是,还没有看到他们在行动。更奇特的是还没有看到任何块参数。我更改了我的软件并将这两个功能作为格式错误的响应处理。 golang 支持 http 预告片。他们将它们用于构建工具“gomote”:youtube.com/…【参考方案4】:

就在最近,据caniuse.com 称,大多数主要浏览器提供商现在在其最新版本(例如 Firefox-88、Safari-14.1、Chrome-88 等)中支持 Trailer 响应标头。

但是,这似乎只是因为他们支持Server-Timing(可以使用另一个答案中提到的预告片),并且目前似乎没有从浏览器javascript访问预告片标头的通用方法- 目前是open issue for the Fetch API,以及trailers in Chrome is marked wontfix 的错误请求。

【讨论】:

以上是关于是否有任何浏览器支持以分块编码响应发送的预告片?的主要内容,如果未能解决你的问题,请参考以下文章

分块传输编码 - 浏览器行为

如何告诉HTTP服务器不发送分块编码

分块编码(Transfer-Encoding: chunked)

HTTP中分块编码(Transfer-Encoding: chunked)

如何使用 Proxygen 和 Folly 发送 HTTP 分块响应以模拟视频流?

分块编码和内容长度标头