Nginx rewrite规则对含#的URL负向预查不生效问题求助
问题根因
URL中#及后面的内容属于哈希片段(fragment),是HTTP协议规定的仅在浏览器端处理的内容,默认不会发送到Nginx服务器。你在Nginx中能拿到的$uri/$request_uri变量完全不包含#及之后的内容,所以带#的/subcategory1路径在Nginx侧完全不可见,你的负向预查规则自然无法匹配到这部分内容,不是正则编写逻辑有问题。
可行解决方案
方案1:切换前端路由模式(最推荐)
如果带#的路径是单页应用的哈希路由,直接把前端路由改成History模式,路径中的#会消失,变成普通的路径结构:
原来的/path/category#/subcategory1会变成/path/category/subcategory1,你原来写的负向预查规则就可以正常生效。
只需要给Nginx加History模式的回退规则即可,示例:
location / { try_files $uri $uri/ /index.html; }
方案2:前端侧做重定向判断
如果必须保留哈希路由模式,直接在前端入口文件中加判断逻辑:读取当前页面的哈希路径,判断是否包含subcategory1,不包含的话直接用JS跳转到目标新域名,比服务端处理更简单直接。
方案3:改造请求传参(适合特殊场景)
如果必须在Nginx侧完成重定向逻辑,要求前端把哈希片段的内容作为查询参数附加到请求URL中,比如/path/category#/subcategory1改成/path/category?hash=/subcategory1,然后修改Nginx规则同时匹配路径和查询参数即可:
if ($args !~* "subcategory1") { rewrite ^/path/category.*$ https://new.host.com permanent; }
优化后的原规则写法
Nginx rewrite正则中不需要转义/,原来的规则可以简化为:
rewrite ^/path/category(?!.*\bsubcategory1\b).*$ https://new.host.com permanent;
内容的提问来源于stack exchange,提问作者Roopendra
相关产品推荐
相关产品推荐

