观察、决策、行动三步示意图,旁边是压缩属于内容协商的英文标题。

压缩协商本质上仍是内容协商

HTTP 压缩选择的是施加了内容编码的表示,不是一种新的媒体类型。经过 gzip 的文本,解压后仍然是文本。因此有效验证需要回答三个问题:编码是否可接受、传输内容是否变小、解码后是否恢复了原本要提供的字节。配置里勾选了压缩,或者接口返回成功状态,都不能同时证明这三件事。 区分缺失、排除与偏好 根据 RFC 9110,Accept-Encoding 缺失时,任何内容编码都被认为可接受;显式空值则表示不希望使用内容编码。identity 代表没有内容编码,通常默认可接受,除非被 identity;q=0 或适用的 *;q=0 排除。通配符还可以让没有逐个列出的编码成为可接受候选,因此“只能发送客户端单独点名的编码”并不是完整规则。 质量值为零表示不可接受,正数则用于表达可接受编码之间的偏好。但服务器还必须具有对应编码器,并判断内容是否适合压缩。客户端偏好 Brotli,不会替服务器安装 Brotli。如果 identity 仍然可接受,未编码响应可能就是合理结果。即使所有候选都被排除,也不能假定每个服务器都会实施严格的 406 策略,因为 RFC 9110 还允许忽略协商偏好。应用需要哪种行为,必须单独验证。 坏掉的样子 代理压缩正文却漏写 Content-Encoding,客户端就可能把压缩字节当成文本;反过来,代理解压后保留原字段,则可能诱发第二次解码。Content-Length 如果存在,描述的是编码后内容的字节数,不是原始长度。流式压缩不一定提前知道最终大小,可以不发送这个字段,而不是继续沿用旧长度。消息分帧与内容编码是不同层次,不能混为一谈。 当 Accept-Encoding 参与可复用变体的选择时,Vary 需要描述这个维度,未编码响应也不能漏掉。否则,缓存中的 gzip 副本可能送给明确排除了 gzip 的客户端。缓存新鲜度和存储资格仍是另外的问题。即使选择正确,也不保证压缩值得:很小的正文存在额外开销,已经压缩过的媒体通常收益有限。应测代表性内容和处理成本,而不是声称所有文本都有一个固定的压缩百分比。 快速验证 准备 Python 3.11 或更新版本、支持 gzip 的 curl,以及 PATH 中的 Caddy 2.11.4。从官方发布页取得适合系统的二进制,并核对公布的校验和后再运行。程序使用回环端口 18765;若该端口占用,应在代码里换成空闲端口。它关闭管理端点、自动 HTTPS 和配置持久化,只清理自己创建的临时文件与子进程,不接触正在运行的网站服务。 ...

七月 21, 2026 · 3 分钟 · XB Field Notes