我正在尝试以分块模式发送数据。所有标头均已正确设置,数据也已相应编码。浏览器将我的响应识别为分块响应,接受标头并开始接收数据。
我期望浏览器会更新每个接收到的块上的页面,而是等到接收到所有块然后将它们全部显示。这是预期的行为吗?
我希望看到每个块在收到后立即显示。使用
curl
时,每个块在收到后立即显示。为什么 GUI 浏览器不会出现同样的情况?他们是否使用某种缓冲/缓存?
我将
Cache-Control
标头设置为 no-cache
,所以不确定它与缓存有关。
afaik 浏览器需要一些有效负载来启动接收到的渲染块。
Curl当然是个例外。
尝试在第一个块之前发送大约 1KB 的任意数据。
如果您所做的一切正确,浏览器应该按照收到的方式渲染块。
修复标题。
Content-type: text/html
,Chrome 中不会发生缓冲。text/plain
,那么仅使用 Content-type: text/event-stream
也会禁用缓冲。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 的文档:
响应 HTTP 标头是一个标记,用于 服务器指示在中通告的 MIME 类型
X-Content-Type-Options
标题不应更改并遵循。这 允许选择退出 MIME 类型嗅探,或者,换句话说,它是一个 可以说网站管理员知道他们在做什么。
Content-Type
因此添加
X-Content-Type-Options: nosniff
就可以了。
无论数据是否分块发送,浏览器都可以在数据到来时对其进行处理和渲染。浏览器是否呈现响应数据将取决于数据结构及其使用的缓冲类型。例如在浏览器渲染图像之前,它需要有文档(或足够的文档)、样式表等。
当生成资源响应时资源的长度未知(“内容长度”不能包含在响应标头中)并且服务器不想在生成后关闭连接时,分块非常有用资源已转移。
设置
Content-type: application/octet-stream
在流式传输 LLM 块时有效 - 即使对于 Firefox!