Accept-Encoding 协商压缩
Accept-Encoding 声明客户端能解压哪些算法,服务端从中挑一个压缩响应体并在 Content-Encoding 里标注实际使用的算法。常见取值有 gzip、deflate、br、zstd,以及表示不压缩的 identity。这个协商是单向的:客户端说「我能收什么」,服务端决定「用哪种」,因此服务端必须确认自己选出的算法确实在客户端的列表里。
基本信息
| 请求头名 | Accept-Encoding |
|---|---|
| 作用 | 声明客户端支持的响应压缩算法 |
| 规范 | RFC 9110 第 12.5.3 节 |
| 常见取值 | gzip、deflate、br、zstd、identity |
| 响应侧对应头 | Content-Encoding 说明实际算法,Vary 说明缓存需要按该头区分版本 |
| 典型权重写法 | gzip, deflate, br, zstd;q=0.9, identity;q=0 |
验证压缩是否生效
验证压缩是否生效
curl -sI -H 'Accept-Encoding: gzip, br' https://www.example.com/ | grep -iE 'content-encoding|content-length|vary'
# content-encoding: br # 服务端实际选择了 brotli
# vary: Accept-Encoding # 缓存必须按该头区分版本
curl -s -H 'Accept-Encoding: gzip' -o /dev/null -w '%{size_download}\n' https://www.example.com/
curl -s -H 'Accept-Encoding: identity' -o /dev/null -w '%{size_download}\n' https://www.example.com/ # 对比体积差异取值与兼容性
| 算法 | 说明 | 适用性 |
|---|---|---|
| identity | 不压缩 | 所有客户端都支持,作为兜底 |
| gzip | 兼容性最好的压缩算法 | 通用场景的默认选择 |
| br | 压缩率通常优于 gzip | 现代浏览器普遍支持,老客户端可能不支持 |
| zstd | 解压速度快且压缩率好 | 需要客户端与服务端同时支持 |
| q 权重 | 表示相对偏好,取值 0 到 1 | q=0 表示不接受,写错会协商出错误结果 |
典型使用场景
- 文本类响应压缩:HTML、JSON、CSS 与 JS 压缩后体积可下降数倍
- 排查响应变慢:确认是否开启了压缩,以及是否发生了重复压缩
- 核对缓存正确性:检查是否带 Vary,避免不同压缩版本互相污染
- 二进制资源排查:确认图片与视频没有被再压一次,避免浪费 CPU
- 网关与源站的分工梳理:确定压缩在哪一层执行最合适
响应用了压缩却没有返回 Vary,中间缓存可能把一个算法的版本发给不支持该算法的客户端,表现为内容乱码或解压失败。压缩与 Vary 必须成对出现。
CDN 与源站同时开启压缩会产生重复压缩:体积不但不会更小,还额外消耗 CPU,抓包看 Content-Encoding 是否被叠加或对比压缩前后体积即可确认。