移动体验 / 方法解读

移动端网页如何通过 Vary 响应头实现内容差异化缓存

当同一 URL 返回不同内容时,通过在响应头中添加 Vary 指令,可以让缓存系统根据请求头(如语言或编码)分别存储不同的响应副本。

HTTP缓存设计思想示意图
主题资料配图,非新闻现场照片 · 配图:读懂「 唱吧ktvhttpcache 」设计思想

为什么同一 URL 会返回不同内容

HTTP 缓存通常基于 URL 来区分响应,即相同的 URL 对应相同的缓存条目。然而,当服务器根据请求头进行内容协商时,相同的 URL 可能会返回不同的响应体。例如,根据 Accept-Language 请求头返回英文或日文内容,或者根据 Accept-Encoding 返回压缩或未压缩的版本。如果缓存系统仅以 URL 为键,就会导致错误的响应被返回给错误的请求。

这种差异化的内容协商在移动端非常常见,比如根据用户的语言偏好或设备能力提供不同的资源。如果不加以区分,缓存机制会将不同语言的页面内容混淆,导致用户看到错误的语言版本,或者无法正确利用压缩带来的性能优势。因此,需要一种机制来告诉缓存系统,哪些请求头决定了响应内容的不同。

Vary 响应头如何指定缓存键

Vary 响应头用于声明影响响应内容的请求头字段。通过在响应头中添加 Vary: Accept-Language,服务器明确告诉缓存系统,对于同一个 URL,需要根据 Accept-Language 请求头的值来分别存储和返回响应。这意味着缓存系统会生成一个复合键,将 URL 和 Accept-Language 的值组合起来作为缓存索引。

一旦设置了 Vary 头,缓存系统就会将响应与特定的请求头条件绑定。例如,对于 https://example.com/index.html,当请求头为 Accept-Language: en 时,缓存会存储英文内容;当请求头为 Accept-Language: ja 时,缓存会存储日文内容。后续的请求会根据其请求头匹配到对应的缓存副本,从而确保返回正确的内容。

如何设置 Vary 响应头

在服务器配置中,可以通过设置响应头来添加 Vary 指令。例如,在 HTTP 响应头中添加 Vary: Accept-Language 或 Vary: Accept-Encoding。这通常在 Web 服务器(如 Nginx 或 Apache)的配置文件中完成,或者在应用程序代码中动态生成响应头。确保在所有返回差异化内容的响应中都包含相应的 Vary 头。

需要注意的是,Vary 头的值可以包含多个请求头字段,例如 Vary: Accept-Encoding, Accept-Language。这表示响应内容会根据这两个请求头的组合而变化。然而,应避免将 User-Agent 放入 Vary 头,因为 User-Agent 的变化极其频繁,这会极大地降低缓存的命中率,导致缓存几乎无法复用。

如何验证 Vary 头是否生效

可以通过浏览器开发者工具的 Network 面板来验证 Vary 头是否正确设置。在查看响应头时,找到 Vary 字段,确认其值是否包含了预期的请求头(如 Accept-Language)。如果 Vary 头不存在或值不正确,说明缓存系统可能无法正确区分不同内容的响应。

为了进一步验证缓存是否按预期工作,可以使用不同的请求头发送请求。例如,先发送 Accept-Language: en 的请求,查看缓存是否存储了对应的响应;然后发送 Accept-Language: ja 的请求,查看是否返回了不同的内容。如果两次请求返回的内容不同,且 Vary 头正确设置,说明缓存系统已成功实现了内容差异化缓存。

资料与延伸阅读

你可以通过以下原始资料核对文中概念,并继续深入阅读。

  1. HTTP caching - HTTP | MDN ↗
  2. 配图:读懂「 唱吧ktvhttpcache 」设计思想 ↗
← 更多移动体验文章返回顶部 ↑