nginx代理缓存支持多语种网站需归一化语言标识并配合vary响应头:用map提取主语言码(如zh/en),加入proxy_cache_key,且必须设置add_header vary accept-language。

要让 Nginx 代理缓存正确支持多语种网站,关键不是简单地把 $http_accept_language 塞进缓存键,而是提取稳定、可归一化的语言标识,并配合 Vary 响应头协同工作——否则缓存会混乱或失效。
提取并标准化语言代码
原始 Accept-Language 值变化多(如 zh-CN,zh;q=0.9,en;q=0.8),直接拼入缓存键会导致大量碎片。应在 http 块中用 map 提前归一化:
map $http_accept_language $lang { ~^zh.* "zh"; ~^en.* "en"; ~^ja.* "ja"; ~^ko.* "ko"; default "en"; }- 避免使用完整 header 或带权重的字符串,只取主语言两字母码
- 未匹配时统一 fallback 到
"en",确保空值/异常 UA 不产生新 key
构造带语言维度的缓存键
在 location 或 upstream 配置中,将标准化后的 $lang 显式加入 proxy_cache_key:
proxy_cache_key "$scheme://$host$uri|$lang|$cookie_user_id";- 若需区分登录态与游客,
$cookie_user_id未登录时设为"guest",避免空值分裂 - 务必包含
$host,防止多租户子域名间缓存污染
必须设置 Vary 响应头
仅改缓存键还不够。CDN 或浏览器缓存需要知道“这个响应依赖 Accept-Language”,否则可能把中文版缓存后返回给英文用户:
- 在对应 location 中添加:
add_header Vary Accept-Language; - 不要写成
Vary: Accept-Language, Cookie等冗余组合,除非你真在 key 中用了这些字段 - 该头会随响应一起发出,告诉所有中间缓存:请按
Accept-Language的实际值分别存取
验证与调试建议
上线前确认三点是否生效:
- 查看响应头是否含
Vary: Accept-Language - 检查
$upstream_cache_status响应头,对比不同语言请求的HIT/MIS状态 - 临时加日志:
log_format cache_log "... $lang $upstream_cache_status";,观察 key 是否按预期分组











