Apache可通过mod_rewrite结合%{HTTP:Accept-Language}实现基于语言的域名重定向,需正确提取语言标签、设置优先级匹配及避免循环重定向。

Apache 本身不直接提供 HTTP_ACCEPT_LANGUAGE 的内置重定向指令,但可以通过 mod_rewrite 模块结合 %{HTTP:Accept-Language} 变量实现基于客户端语言的域名重定向。关键在于正确提取语言标签(如 zh-CN、en-US、ja)、合理匹配优先级,并注意浏览器发送语言的格式与顺序。
✅ 正确获取语言字段的方式
使用 Apache 变量:
%{HTTP:Accept-Language}不是 %{HTTP_ACCEPT_LANGUAGE}(这是旧版写法,部分版本兼容但不推荐),也不是 %{HTTP_ACCEPT_LANGUAGE_STRING}(根本不存在)。
示例请求头值:
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Apache 中该变量值就是完整字符串,需用正则提取主语言或带区域的语言代码。
✅ 匹配中文用户并重定向到 zh.example.com
RewriteEngine On
# 先排除不需要重定向的情况(可选,如爬虫、特定UA)
RewriteCond %{HTTP_USER_AGENT} !^(.*bot.*|Googlebot|BingBot) [NC]
# 匹配 Accept-Language 开头为 zh 或包含 zh-CN/zh-TW 等
RewriteCond %{HTTP:Accept-Language} ^zh [NC,OR]
RewriteCond %{HTTP:Accept-Language} ,zh- [NC]
# 确保当前不是目标域名,避免循环
RewriteCond %{HTTP_HOST} !^zh\.example\.com$ [NC]
# 执行重定向(临时跳转便于调试)
RewriteRule ^(.*)$ https://zh.example.com/$1 [R=302,L]⚠️ 注意:
[NC,OR]表示“不区分大小写”且“满足任一条件即通过”,但后续RewriteCond仍需全部满足才触发RewriteRule。此处两个语言条件是“或”关系,第三条是“且”关系(非目标域名)。
Apache Superset Dashboard and SQL Exploration Skill下载Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
✅ 匹配多语言并分发到不同子域(推荐结构)
RewriteEngine On
# 优先匹配更具体的区域语言(如 zh-CN > zh)
RewriteCond %{HTTP:Accept-Language} (zh-CN|zh-SG|zh-Hans) [NC]
RewriteCond %{HTTP_HOST} !^zh\.example\.com$ [NC]
RewriteRule ^(.*)$ https://zh.example.com/$1 [R=302,L]
RewriteCond %{HTTP:Accept-Language} (zh-TW|zh-HK|zh-Hant) [NC]
RewriteCond %{HTTP_HOST} !^zh-hk\.example\.com$ [NC]
RewriteRule ^(.*)$ https://zh-hk.example.com/$1 [R=302,L]
RewriteCond %{HTTP:Accept-Language} ^en [NC,OR]
RewriteCond %{HTTP:Accept-Language} ,en- [NC]
RewriteCond %{HTTP_HOST} !^en\.example\.com$ [NC]
RewriteRule ^(.*)$ https://en.example.com/$1 [R=302,L]
RewriteCond %{HTTP:Accept-Language} ^ja [NC,OR]
RewriteCond %{HTTP:Accept-Language} ,ja- [NC]
RewriteCond %{HTTP_HOST} !^ja\.example\.com$ [NC]
RewriteRule ^(.*)$ https://ja.example.com/$1 [R=302,L]✅ 说明:
- 每组
RewriteCond+RewriteRule是独立逻辑段; -
[L]确保匹配后停止后续规则,防止误覆盖; - 使用
R=302调试阶段务必如此,上线前再改为R=301; -
$1保留原始路径,保证/about→https://zh.example.com/about。
✅ 避免常见陷阱
-
语言字段为空时规则失效:某些老旧客户端或命令行工具(如 curl 默认不发
Accept-Language),此时变量为空字符串,所有RewriteCond不匹配,自然走默认站点——这是预期行为,无需额外处理。 -
逗号分隔与权重(q=)不影响匹配:正则只看字符串是否存在,
q=权重值无需解析。 -
大小写敏感问题:语言标签标准是小写(如
zh-cn),但浏览器可能发zh-CN;加[NC]安全。 -
不要用
Redirect指令替代:Redirect无法读取Accept-Language,仅支持 Host、Path、Query 等静态条件。
✅ 验证与调试建议
-
开启 rewrite 日志(仅开发环境):
LogLevel alert rewrite:trace3
查看
/var/log/apache2/error.log中重写过程。 -
用 curl 模拟不同语言请求:
curl -H "Accept-Language: zh-CN,zh;q=0.9" -I http://example.com/ curl -H "Accept-Language: en-US,en;q=0.8" -I http://example.com/
在浏览器开发者工具 Network 标签中检查请求头和响应状态码。
不复杂但容易忽略细节。


















