9 月 22 日 Cloudflare 的官方博客发了篇自嘲式标题的文章,HTTP 里最难看的部分,我们支持了,说的就是 Vary 响应头。我把官方博客和开发者文档对了一遍,又看了 HN 上一百五十分的讨论,这件事对做网站的人分量不小。
主要功能
先补背景。Vary 是 HTTP 标准里的响应头,用来告诉中间缓存,同一个网址会按哪些请求头返回不同内容,比如按 Accept 头返回 HTML 还是 JSON,按 Accept-Language 返回哪种语言,这套机制叫内容协商。Cloudflare 此前对图片以外的响应基本忽略 Vary,这让按请求头做内容协商的站点很受伤,缓存层等于形同虚设,做 API 网关与多语言站的运维应该深有体会。
这次上线的能力落在缓存规则里。每条规则可以对参与 Vary 的头分别选三种动作。normalize 是官方推荐的默认,对 Accept、Accept-Language、Accept-Encoding 做完整规范化,MIME 类型转小写、按质量值排序、去掉参数、美式英语归并进英语大类,支持的媒体类型与语言清单都能配白名单,规范化后的头还会回传源站;passthrough 按原始字节匹配,大小写顺序差异都算不同变体;bypass 则是该头一旦参与 Vary 就不缓存,官方建议 Cookie 和 User-Agent 走这条路。Workers 的子请求另有一条配置口,控制台、规则接口与 Terraform 三种方式都能配,全部套餐可用,免费版也在内,但默认不开启,需要自己建规则,而且源站必须真的返回 Vary 头,错误响应也要一致,两边配合才生效。顺带分清一件事,2021 年那批针对图片的 Vary 处理是另一套独立机制,这次的新能力面向通用响应。
为什么要这么谨慎,博客给了组数据。对近五万个站点超 1.2 亿个响应的分析显示,约三千个站点在四个以上字段上做 Vary,最多的一个用了四十七个字段,三个头十种取值就能组合出一千个缓存变体,缓存碎成这样,官方的形容是完全正确且几乎永远冰凉。这组数字是官方引用的自称口径。
解决了什么需求
做内容协商的站点等这一天等了太多年。HN 用户 simonw 就是 Simon Willison,他说盼这个功能盼了很多年,以前 Cloudflare 可能把 JSON 版本缓存后错发给要 HTML 的用户,这类设计在它家缓存后面根本没法部署。用户 xyzzy_plugh 的感慨更直接,以为这辈子等不到了,2026 年终于有真正的内容协商。用户 itake 的反应最短,等的就是这个,干得好。用户 bhouston 讲了个反面故事,当年误以为 Cloudflare 支持 Vary,在线上踩出严重故障。用户 yellow_lead 的站点按语言头输出动态内容,以前这些页面无法缓存,现在看到希望。质疑声也值得记。用户 rob-olmos 追问无 Vary 头的旧缓存对象会不会抢先命中;用户 charcircuit 担心英语变体归并让美国访客看到英式拼写。最扎心的来自用户 sandeepkd,他说作为中间人早该实现协议既有语义,猜是被某个足够大的客户逼出来的。还有用户顺路抱怨了别家企业功能下放的旧账。
上手流程
Cloudflare 控制台进缓存规则,新建或编辑规则,找到 Vary 设置,对每个参与协商的头选动作,Accept 家族用 normalize,Cookie 与 User-Agent 用 bypass,保存后记得验证源站响应头确实带着 Vary。改动可以用规则接口或 Terraform 进版本管理,团队协作不用在控制台里手点。清缓存时注意,清一个网址会连同它的全部变体一起清掉。
注意事项
规范化会改写回传源站的头,依赖原始头做逻辑的源站先测试。官方文档页脚的时间戳与博客发布时间存在出入,功能上线节奏以博客为准,配置前以自己账号里实际看到的选项为准。缓存命中率提升多少,目前没有第三方量化数据,自己开规则前后对比最实在,升级前后各跑一遍缓存命中统计,提升一目了然,早配早受益,就这么简单。
总结
老标准的老补丁,免费套餐就能用。做 API 内容协商与多语言站点的运维值得当天就配,配置只要十分钟,收益是长年的。观望的看一周社区反馈,坑踩完再上。
来源
- Cloudflare 官方博客 https://blog.cloudflare.com/vary-support/
- 官方开发者文档 https://developers.cloudflare.com/cache/concepts/vary/
- HN 讨论 https://news.ycombinator.com/item?id=49823195