nginx可通过map指令提取并匹配accept-language请求头,将不同语言请求路由至对应upstream集群,无需第三方模块,兼容≥1.11.0版本,且比if判断更高效安全。

Nginx 本身不直接解析客户端语言(如 Accept-Language 请求头),但可以通过提取该请求头内容,结合 map 指令做条件映射,再将请求分发到不同 upstream 或静态目录——这是实现“基于客户端语言路由”的标准且轻量的方式。
提取并映射 Accept-Language 头
在 http 块顶层定义 map,把语言标签(如 zh-CN、en-US、ja)映射为后端集群名或路径变量:
- 用
$http_accept_language获取原始请求头值 - 正则匹配常见语言前缀(注意顺序:更具体的先写,如
zh-CN在zh之前) - 必须设
default,避免未匹配时变量为空导致 502
示例配置:
map $http_accept_language $lang_upstream {
default app-global;
~*zh-CN app-zh;
~*zh-TW app-zh;
~*zh app-zh;
~*en-US app-en;
~*en-GB app-en;
~*en app-en;
~*ja app-ja;
~*ko app-ko;
}
定义对应后端集群
在同一个 http 块中,为每个语言组声明 upstream:
- 每个 upstream 可包含一个或多个真实服务节点
- 支持权重、健康检查等常规参数
- 名称需与 map 中的值严格一致(如
app-zh)
例如:
upstream app-zh {
server 10.0.1.10:8080 weight=3;
server 10.0.1.11:8080;
}
upstream app-en {
server 10.0.2.20:8080;
server 10.0.2.21:8080;
}
upstream app-global {
server 10.0.3.30:8080;
}
在 location 中完成转发
在 server 块内,用 proxy_pass 引用映射后的变量:
- 写法必须是
proxy_pass http://$lang_upstream;(末尾不加/) - 保留原始 URI 路径,避免路径被截断
- 补全必要代理头,确保后端能识别真实客户端和协议
典型 location 示例:
location / {
proxy_pass http://$lang_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
补充说明与注意事项
这种方案不依赖第三方模块,兼容所有主流 Nginx 版本(≥1.11.0),但要注意几点:
- 浏览器发送的
Accept-Language可能含多个值(如zh-CN,zh;q=0.9,en-US;q=0.8),map 默认只匹配第一个成功项,无需额外处理 - 若需更高精度(如区分简体/繁体),可配合更长的正则(如
~*zh-CN(;|$))防止误匹配 - 不建议在
if中做语言判断——性能差且易出逻辑错误,map 是更安全、更高效的选择 - 若同时使用 CDN 或前置代理,需确认
$http_accept_language是否被透传;必要时用real_ip模块还原真实头











