Nginx环境下WordPress WPML站点URL路径重写问题
原配置触发双404的核心原因
- 正则匹配范围过窄:原规则仅匹配en语言的路径,完全没有覆盖es等其他语言的请求;同时规则里的
\w+\.?.*仅能匹配单段、无斜杠的子路径,遇到带分类、多级层级的文章地址时完全无法匹配,重写逻辑根本不生效。 - 重写标识使用错误:规则里用的
last是Nginx内部重写标识,执行后会重新走一遍location匹配流程,但此时重写后的新路径没有对应的路由适配(WPML本身还在按旧的路径结构解析请求),WordPress无法识别对应内容,自然触发404;同时原请求被内部重写劫持,旧路径原本正常的WP处理流程被打断,旧地址也会一起404。 - 逻辑目标缺失:就算内部重写流程正常,用户看到的地址栏内容不会变化,搜索引擎也感知不到URL变更,完全达不到迁移URL结构的目的。
可行的Nginx配置方案
如果一定要通过Nginx层面完成URL迁移,将下面的规则放在现有WordPress伪静态规则的最前面(location /块内部):
# 301永久跳转旧的 /blog/语言代码/xxx 到新的 /语言代码/blog/xxx rewrite ^/blog/(es|en)/(.*)$ /$1/blog/$2 permanent;
特别提醒:
- 对外跳转必须用
permanent(对应301状态码),不要用last,否则不仅地址栏不会变化,还容易触发Nginx的重定向死循环。- 这个规则只负责完成旧地址到新地址的跳转,跳转完成后的新地址请求,必须保证WordPress/WPML能正常解析,否则就算跳转逻辑正常,访问新地址还是会404。需要同步在WPML的设置里把语言代码的路径前缀位置调整到站点根路径下,和新的URL结构保持一致。
更优的实现方案
完全不需要手动在Nginx层面写重写规则,直接通过WPML的内置配置完成调整即可,可靠性远高于手动写服务器规则:
- 进入WPML的语言设置页面,找到语言URL格式的配置项,将原来“语言代码作为blog子路径”的结构,调整为“语言代码作为站点根路径的第一层路径”的结构
- 保存配置后,进入WordPress固定链接设置页面,点击一次“保存更改”刷新伪静态规则
- WPML会自动为所有内容生成对应的新URL,同时内置的兼容性机制会自动对所有旧结构的URL做301永久跳转,不需要额外手写Nginx规则,后续新增的多语言内容也会自动匹配新的URL结构,不会出现规则漏匹配的问题
内容的提问来源于stack exchange,提问作者same_day
相关产品推荐
相关产品推荐

