【问题标题】:Nginx Rewrite with Regex Multiple Token (+)使用正则表达式多个令牌 (+) 重写 Nginx
【发布时间】:2016-12-11 06:59:54
【问题描述】:

当涉及到多个令牌编号时,我在重写时遇到了一些问题。

我正在对我们的 API 进行版本控制,因此不推荐使用的版本调用将转到我们的最新版本。为简单起见,假设我们支持v4v5。当一些点击我们的v1-3 时,我们需要它转到v5。同样,如果有人点击v6,它也应该转到v5

我们的 nginx.conf 使用 proxy_pass 和上游,所以我让每个版本在不同的端口上运行

upstream v4 {
  server 127.0.0.1:3000
}

upstream v5 {
  server 127.0.0.1:3001
}

然后我们使用位置块来代理

location ^~ /v5 {
  proxy_pass $scheme://v5;
}

location ^~ /v4 {
  proxy_pass $scheme://v4;
}

location ~* "^/v[0-9]+" {
    rewrite ^/v[0-9]+/(.*)$ /$latestVersion/$1;
    proxy_pass $scheme://$latestUpstream;
}

最后一个位置块适用于v0-9,但当号码是多个数字时无法捕获,例如v11,即使我使用的是+

对此的任何帮助都会很棒。真的被这个弄糊涂了。谢谢!

【问题讨论】:

    标签: nginx nginx-location


    【解决方案1】:

    在以下块中:

    location ~* "^/v[0-9]+" {
        rewrite ^/v[0-9]+/(.*)$ /$latestVersion/$1;
        proxy_pass $scheme://$latestUpstream;
    }
    

    rewrite 语句执行隐式rewrite ... last,这意味着 URI 最终由 location ^~ /v5 块处理,从而使该块中的 proxy_pass 语句几乎是多余的。有关rewrite 语法,请参阅this document

    当 URI 单独显示为版本字符串时,rewrite 匹配失败没有尾随 /,例如/v11.

    您需要将版本字符串后面的/ 设为可选。试试:

    location ^~ /v {
        rewrite ^/v[0-9]+(/.*)$ /$latestVersion$1 last;
    }
    

    正则表达式 location 块可能是不必要的,所以我用 更短的 前缀替换了 location(请参阅 this document 了解 location 语法)。

    我添加了一个last 后缀以明确rewrite 的意图。


    编辑:回复您的评论

    单独使用前缀 location 块区分 URI /v5/v51(即没有尾随 /)是有问题的。如果 URI always 在版本字符串之后(至少)有一个尾随 /,则只需在两个现有的 location 块中添加尾随 / 即可轻松解决。

    但假设您需要像 /v5/v51 这样的短 URI 来工作,您应该将解决方案切换为正则表达式 location 块。

    请注意,正则表达式 location 块的计算方式不同,并且该顺序很重要。您可能需要将这些 location 块移到其他正则表达式 location 块之前,以防止它们被配置文件中的其他代码覆盖。

    例如:

    location ~* ^/v5(/|$) {
        proxy_pass $scheme://v5;
    }
    location ~* ^/v4(/|$) {
        proxy_pass $scheme://v4;
    }
    location ~* ^/v[0-9] {
        rewrite ^/v[0-9]+(/.*)$ /$latestVersion$1 last;
    }
    

    请注意,修饰符已更改为~*,它引入了一个正则表达式(并且还使其不区分大小写——这对您可能很重要,也可能不重要)。

    【讨论】:

    • 感谢您的解释,这真的很有帮助。我发现了一个意外行为,其中/v40..9/v50...9 分别转到/v4/v5 位置,我希望它们被/v 位置捕获。你对此有什么建议吗?我尝试像(/|$) 那样做正则表达式,但没有奏效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多