语言协商请求头
Accept-Language 让客户端声明期望的自然语言,取值是 RFC 5646 定义的语言标签,并可用 q 值表示优先级,例如 zh-CN,zh;q=0.9,en;q=0.8。服务端据此选择本地化内容,并在响应里用 Content-Language 说明实际返回的语言。它只是协商建议,服务端完全可以忽略。
基本信息
| 方向 | 请求头,响应侧对应 Content-Language |
|---|---|
| 规范 | RFC 9110 §12.5.4,语言标签见 RFC 5646 |
| 语法 | 语言标签列表,逗号分隔,可带 q 值(0 到 1,默认 1) |
| 通配符 | 星号表示接受任意语言,通常用于兜底 |
| 浏览器行为 | 由浏览器按系统与用户设置自动发送,页面切换一般另用 Cookie |
取值读法
| 取值 | 含义 | 说明 |
|---|---|---|
| zh-CN | 简体中文(中国) | 主标签加地区子标签,最常见的写法 |
| zh;q=0.9 | 中文,优先级 0.9 | q 值越小优先级越低 |
| en-US,en;q=0.9 | 美式英语优先,其次任意英语 | 浏览器典型输出 |
| 星号;q=0.1 | 任意语言兜底 | 其它候选都不匹配时使用 |
观察协商结果
观察协商结果
curl -si https://www.example.com/ -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8' \
| grep -i -E 'content-language|vary'
# content-language: zh-CN
# vary: Accept-Language ← 参与缓存时必须有它典型使用场景
- 首访用户未选语言时给一个合理默认值,减少手动切换
- 多语言站点做 SEO 时结合 hreflang 与 Content-Language 标示语言版本
- 排查「返回内容语言不对」:确认 CDN 是否按该头做了缓存分片
- 对比不同地区用户的默认语言是否符合预期
大多数站点以页面手动切换为准,Accept-Language 只做首访默认值;不要拿它做访问控制或地域封禁依据,它完全由客户端控制,改一个请求头就能伪造。
语言协商结果参与缓存时必须带 Vary: Accept-Language,否则会把先到的语言版本缓存下来发给所有用户,出现「日语用户看到中文页」这类问题。
多语言站点的常规做法是三级回退:URL 或 Cookie 里的显式选择优先,其次按 Accept-Language 协商,最后落到站点默认语言,并把最终选择写回 Cookie,避免每次请求都重新协商。