【问题标题】:Regex to redirect two different URLs starting with the same string正则表达式重定向两个以相同字符串开头的不同 URL
【发布时间】:2021-03-19 01:56:00
【问题描述】:

这是我的两条 nginx 规则:

rewrite ^(/v1/foobar)(.*)$ /final$2 permanent;
rewrite ^(/v1/foobar-tow)(.*)$ /final$2 permanent;

我希望/v1/foobar-two/foo 将使用第二条规则,然后重定向到/final/foo,但我没有:因为 URL 以 foobar 开头,所以将使用第一条规则,最后将重定向到 @987654325 @ : 第一个目标的拼接和第一条规则和第二条规则的区别!

为了解决这个问题,我只是颠倒了规则,但我想知道是否有更好的解决方案!

总之,这就是我要找的:

  • /v1/foobar -> /final
  • /v1/foobar/hello -> /final/hello
  • /v1/foobar-tow -> /final
  • /v1/foobar-tow/hola -> /final/hola

【问题讨论】:

  • rewrite 规则正在由 nginx 从头到尾处理,只需交换它们就可以了。
  • 第一次重写足够松以捕获第二次,因此它可能永远不会评估第二个条件。
  • 您可能需要^(/v1/foobar)(/.*)?$ 作为第一条规则。斜线将要求整个子部分与 foobar 部分匹配。
  • 您可以使用^(/v1/foobar(?:-tow)?)(.*)$将其合并为一条规则
  • @MonkeyZeus 确实是最好的答案!但是,这可以简化为 rewrite ^/v1/foobar(?:-tow)?(.*) /final$1 permanent;(不需要两个捕获组)。

标签: regex nginx redirect


【解决方案1】:

为避免 NGINX 和 increase configuration scalability 出现意外,您通常应该:

  • 尝试在没有rewrite 指令的情况下生活;根据 NGINX 作者的说法,它只是出现在 location 之前,在许多情况下,您现在可以使用 location 和捕获组来代替 rewrite
  • 如果可能的话,以匹配顺序不重要的方式设计正则表达式
  • 在适用的情况下使用精确匹配
  • 在一个前缀下隔离正则表达式位置

把所有东西放在一起:

location /v1/ {
    location = /v1/foobar {
        return 301 /final;
    } 

    location ~ ^/v1/foobar/(\w+)$ {
        return 301 /final/$1;
    }

    location = /v1/foobar-tow  {
        return 301 /final;
    }

    location ~ ^/v1/foobar-tow/(\w+)$ {
        return 301 /final/$1;
    }
}

【讨论】:

  • 我怀疑这个是否会准确捕获 /v1/foobar//v1/foobar-tow/ URI。好的,我们可以添加两个更精确匹配的位置或修改正则表达式,但你确定这款游戏物有所值吗?不要为每个请求只匹配一个正则表达式,而是有两个正则表达式匹配位置?顺便说一句,你不知道吗,在大多数 nginx 构建中,PCRE JIT 的使用仍然默认禁用吗?
  • 它看起来确实很长,但最终(恕我直言)在一段时间后似乎比rewrite更具可读性:) PCRE JIT support 在最近自动出现构建,但您仍然必须使用 pcre_jit on; 在配置中显式启用它
猜你喜欢
  • 2022-01-16
  • 2015-08-11
  • 1970-01-01
  • 1970-01-01
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多