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

Dan*_* El 23 browser firefox google-chrome http

我正在尝试以分块模式发送数据.正确设置所有标头并相应地编码数据.浏览器将我的响应识别为分块,接受标头并开始接收数据.

我期待浏览器会在每个收到的块上更新页面,而是等待直到收到所有块然后全部显示它们.这是预期的行为吗?

我希望看到每个块在收到后立即显示.使用时curl,每个块在收到后立即显示.为什么GUI浏览器不会发生同样的情况?他们使用某种缓冲/缓存吗?

我将Cache-Control标头设置为no-cache,所以不确定它是否与缓存有关.

小智 17

afaik浏览器需要一些有效负载来开始渲染块.
卷曲当然是个例外.

尝试在第一个块之前发送大约1KB的任意数据.

如果您正确地执行所有操作,浏览器应该在收到时呈现块.


Dan*_*l F 7

修复您的标题。


1) 截至 2019 年,如果您使用Content-type: text/html,Chrome 中不会发生缓冲。


2) 如果您只想流式传输文本,类似于text/plain,那么仅使用Content-type: text/event-stream也将禁用缓冲。


3) 如果您使用Content-type: text/plain,那么 Chrome 仍将缓冲 1 KiB,除非您另外指定X-Content-Type-Options: nosniff.

RFC 2045 规定,如果没有Content-Type指定,Content-type: text/plain; charset=us-ascii则应假定

5.2. 内容类型默认值

此协议将没有 MIME Con​​tent-Type 标头的默认 RFC 822 消息视为 US-ASCII 字符集中的纯文本,可以明确指定为:

Content-type: text/plain; charset=us-ascii
Run Code Online (Sandbox Code Playgroud)

如果未指定 Content-Type 标头字段,则采用此默认值。还建议在遇到语法上无效的 Content-Type 标头字段时假定此默认值。在存在 MIME-Version 头域且不存在任何 Content-Type 头域的情况下,接收用户代理也可以假设纯 US-ASCII 文本是发送者的意图。在没有 MIME-Version 或存在句法无效的 Content-Type 标头字段的情况下,仍然可以假定纯 US-ASCII 文本,但发送者的意图可能并非如此。

浏览器将开始缓冲text/plain一定量,以检查它们是否可以检测发送的内容是否真的是纯文本或某种媒体类型(如图像),以防Content-Type省略,则等于text/plain内容类型。这称为 MIME 类型嗅探。

Mozilla将MIME 类型嗅探定义为:

在没有 MIME 类型的情况下,或者在某些浏览器认为它们不正确的情况下,浏览器可能会执行 MIME 嗅探——通过查看资源的字节来猜测正确的 MIME 类型。

每个浏览器在不同的情况下以不同的方式执行 MIME 嗅探。(例如,如果发送的 MIME 类型不合适,Safari 将查看 URL 中的文件扩展名。)存在安全问题,因为某些 MIME 类型表示可执行内容。服务器可以通过发送 X-Content-Type-Options 标头来防止 MIME 嗅探。

根据Mozilla 的文档

X-Content-Type-Options响应的HTTP标头是由服务器使用以指示在通告的MIME类型的标记 Content-Type标头不应该被改变,并且被遵循。这 允许选择退出 MIME 类型嗅探,或者换句话说,这是一种表示网站管理员知道他们在做什么的方式。

因此添加X-Content-Type-Options: nosniff使其工作。

  • 对我来说,“charset=xxxx”是关键。仅使用“Content-type: text/plain”(在 Firefox 60.0.9esr 中),输出会被缓冲,并且仅在接收数据结束时一次性显示。当更改为 `Content-type: text/plain; charset=us-ascii` (或 `Content-type: text/html; charset=utf8`)突然分块渐进式 Web 渲染按预期工作。 (2认同)
  • @MatijaNalis,应该是`内容类型:text/html;charset=utf-8`(如果大小写重要,则为 UTF-8) (2认同)