在Vary: Accept-Language的情况下,浏览器是否应该为不同语言发送不同的If-None-Match值?

前端开发 2026-07-09

我有一个本地化的端点,根据 Accept-Language 请求头返回不同的内容。

响应包含:

Vary: Accept-Language
ETag: "12345"

一个重要的细节是ETag仅从资源内容/版本生成,并不包含语言。换句话说,同一个ETag可能对应不同语言的表示。

例如:

GET /api/locale
Accept-Language: en

HTTP/1.1 200 OK
Vary: Accept-Language
ETag: "12345"

之后:

GET /api/locale
Accept-Language: de

HTTP/1.1 200 OK
Vary: Accept-Language
ETag: "12345"

我的理解是 Vary: Accept-Language 告诉缓存,不同 Accept-Language 值的响应应该被视为独立的缓存条目。

鉴于此,我希望浏览器对每种语言变体维护独立的缓存条目(以及缓存验证器)。

问题:

  1. 根据HTTP规范,当 Accept-Language 头部发生变化时,浏览器发送相同的 If-None-Match 值是否正确?
  2. Vary: Accept-Language 是否意味着浏览器应该为每种语言变体保留独立的ETag验证器?
  3. 如果服务器故意为所有语言变体使用相同的ETag,是否存在缓存陷阱或正确性问题?

我对RFC的要求以及现代浏览器(如Chrome、Firefox、Edge)的实际表现都感兴趣。

解决方案

规范明确,ETag 值对于同一资源的不同表示应该是唯一的。也就是说,服务器通常不应为英语和德语版本返回相同的 ETag。因此问题3 的答案是肯定的:使用相同的 ETag 会带来正确性问题。

来自RFC 9110,第8.8.3节(https://datatracker.ietf.org/doc/html/rfc9110#section-8.8.3):

实体标签是一种不透明的验证器,用于区分同一资源的多种表示,无论这些表示是否因为资源状态随时间变化、内容协商导致多种表示在同一时间内有效,还是两者兼有。

8.8.3.3节 给出了一个涉及内容协商的具体示例,并对这两种表示使用了不同的 ETags

你的直觉在某种程度上也有道理,因为 Vary 确实会导致不同的缓存键。但是,在客户端找到匹配的缓存条目,与在服务器端验证两种表示是否相同,是两个不同的概念。

因此,你的前两个问题并不真正相关。ETags 应该对每种表示唯一,因此浏览器可以在不影响正确性的情况下,在内容协商之外,在 If-None-Match 发送它们。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章