多语言网站路径重写需区分301跳转与内部重写:对外旧链接(如参数式url或错误大小写)必须301跳转以保seo;对内语言路径(如/en/blog)应静默映射到后端,不改变地址栏。

区分跳转与重写:先搞清你要做什么
常见误区是把所有语言路径都用 R=301 强制跳转。其实:
- 用户或搜索引擎访问的是
/en/product→ 你想让它显示英文内容,这属于内部转发,不该跳转; - 老版本 URL 是
/product.php?lang=en→ 现在要换成/en/product,这个旧地址必须301 跳转到新路径; - 用户误输
/EN/product(大写)或/eng/product(错拼),可选择性 301 重定向到标准格式,避免重复内容。
语言前缀跳转:规范入口,避免大小写/拼写歧义
若已确定主语言路径为小写且使用标准代码(如 /zh/、/en/、/ja/),可用 RewriteCond 拦截非常规写法并 301 修正:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/(EN|En|english|ENG)/ [NC]
RewriteRule ^(.*)$ /en/%1 [R=301,L]
RewriteCond %{REQUEST_URI} ^/(ZH|zH|cn|chinese)/ [NC]
RewriteRule ^(.*)$ /zh/%1 [R=301,L]
注意:[NC] 忽略大小写,%1 引用的是 RewriteCond 中捕获的子路径(如 /EN/about → /en/about),末尾不带 ? 是因为这里没涉及查询字符串。
旧参数式 URL 到新路径的 301 跳转
例如原链接 /page.php?lang=ja&id=123 需跳转为 /ja/page/123,必须用 %{QUERY_STRING} 提取参数:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
RewriteCond %{QUERY_STRING} ^lang=ja&?id=([0-9]+)
RewriteRule ^page\.php$ /ja/page/%1? [R=301,L]
说明:
-
%{QUERY_STRING}获取问号后全部参数串; -
%1是RewriteCond中第一个括号捕获的内容(即123); - 结尾的
?表示清空原始查询字符串,防止跳转后变成/ja/page/123?lang=ja&id=123。
语言路由的内部重写(非跳转)
用户访问 /en/blog,你希望它实际执行 index.php?lang=en§ion=blog,但浏览器地址栏不变——这就用内部重写,不加 R 标志:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]{2})/(.*)$ index.php?lang=$1&path=$2 [L,QSA]
说明:
-
^([a-z]{2})/(.*)$匹配两位小写字母开头的路径,如/en/news; -
[QSA]保留原始 URL 中可能带的额外参数,比如/en/contact?ref=footer→index.php?lang=en&path=contact&ref=footer; -
!-f和!-d排除真实存在的文件和目录(如/en/style.css不会被重写)。










