Nginx如何通过正则匹配移除URL部分内容实现重定向?
Nginx如何通过正则匹配移除URL部分内容实现重定向?
嗨,我来帮你搞定这个Nginx重定向的问题!你想要把类似example.com/some-urltext-nav.html的URL重定向到example.com/some-urltext.html,也就是只移除-nav这部分,你的思路是对的,但问题大概率出在规则的放置位置或者匹配优先级上。
先看你的配置:你在HTTP(80端口)和HTTPS(443端口)的两个server块里,都把重定向规则嵌套在了location /里面,但Nginx的location匹配是有优先级顺序的,嵌套的正则规则可能被其他更早匹配的规则(比如静态文件的location)给“抢”走了请求,导致你的重定向没生效。
正确的调整方案
我给你两种可行的修改方式,选哪种都可以:
方式一:调整规则位置,确保优先匹配
把你的重定向location规则移到location /的最前面,这样Nginx会先检查这个正则匹配,再处理其他规则。修改后的location /块大概是这样:
location / { # 把重定向规则放在最前面,确保优先匹配 location ~ ^/(?<capture>.+)-nav\.html$ { return 302 /$capture.html; # 要是需要永久重定向(对SEO友好)就改成301 } location ~ [^/]\.ph(p\d*|tml)$ { try_files /does_not_exists @php; } location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ { expires 365d; } }
这个正则^/(?<capture>.+)-nav\.html$是没问题的,(?<capture>.+)会捕获-nav前面的所有内容,然后通过return指令跳转到拼接后的URL。
方式二:用rewrite指令直接写在server块里
如果你觉得嵌套location麻烦,也可以把重定向规则直接放在server块的开头(在location /之前),用rewrite指令实现:
server { server_name example.com cdn.example.com www.example.com; charset off; index index.php index.html; # 直接写在server块里,全局生效 rewrite ^/(.*)-nav\.html$ /$1.html temporary; # temporary对应302,permanent对应301 # 后面的其他配置保持不变... disable_symlinks if_not_owner from=$root_path; include /etc/nginx/vhosts-includes/*.conf; ... }
这种方式更直接,所有符合规则的请求都会先被rewrite处理,不会被其他location干扰。
注意事项
- 记得同时修改HTTP和HTTPS两个server块,不然其中一个端口的重定向会失效。
- 修改完配置后,先执行
nginx -t检查配置是否正确,没问题再重启Nginx生效:systemctl restart nginx(根据你的系统可能是service nginx restart)。 - 你可以用
curl -I http://example.com/some-urltext-nav.html测试一下,看看返回的响应头里Location字段是不是指向了正确的URL。
备注:内容来源于stack exchange,提问作者Oleksandr




