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

问题描述 投票:0回答:4

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

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

我希望看到每个块在收到后立即显示。使用

curl
时,每个块在收到后立即显示。为什么 GUI 浏览器不会出现同样的情况?他们是否使用某种缓冲/缓存?

我将

Cache-Control
标头设置为
no-cache
,所以不确定它与缓存有关。

http google-chrome firefox browser
4个回答
22
投票

afaik 浏览器需要一些有效负载来启动接收到的渲染块。
Curl当然是个例外。

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

如果您所做的一切正确,浏览器应该按照收到的方式渲染块。


13
投票

修复标题。


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

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

  1. 如果您使用
    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 Content-Type 标头的默认 RFC 822 消息 通过此协议为 US-ASCII 字符集中的纯文本, 可以明确指定为:

Content-type: text/plain; charset=us-ascii

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

浏览器将开始缓冲一定量的

text/plain
,以检查是否可以检测发送的内容是否真的是纯文本或某种媒体类型(例如图像),以防省略
Content-Type
,则等于
text/plain
内容类型。这称为 MIME 类型嗅探。

MIME 类型嗅探 由 Mozilla 定义为:

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

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

根据Mozilla 的文档

X-Content-Type-Options
响应 HTTP 标头是一个标记,用于 服务器指示在中通告的 MIME 类型
Content-Type
标题不应更改并遵循。这 允许选择退出 MIME 类型嗅探,或者,换句话说,它是一个 可以说网站管理员知道他们在做什么。

因此添加

X-Content-Type-Options: nosniff
就可以了。


1
投票

无论数据是否分块发送,浏览器都可以在数据到来时对其进行处理和渲染。浏览器是否呈现响应数据将取决于数据结构及其使用的缓冲类型。例如在浏览器渲染图像之前,它需要有文档(或足够的文档)、样式表等。

当生成资源响应时资源的长度未知(“内容长度”不能包含在响应标头中)并且服务器不想在生成后关闭连接时,分块非常有用资源已转移。


0
投票

设置

Content-type: application/octet-stream
在流式传输 LLM 块时有效 - 即使对于 Firefox!

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.