Regex Nginx location语句在正则表达式和普通匹配中的行为不同

Regex Nginx location语句在正则表达式和普通匹配中的行为不同,regex,nginx,Regex,Nginx,我在这两种情况下看到了不同的行为: location ~ /(?<version>v[12]) { proxy_pass https://localhost/api/$version; } location /v2 { proxy_pass https://localhost/api/v2; } location~/(?v[12]){ 代理通行证https://localhost/api/$version; } 位置/v2{ 代理通行证https://localh

我在这两种情况下看到了不同的行为:

location ~ /(?<version>v[12]) {
    proxy_pass https://localhost/api/$version;
}

location /v2 {
    proxy_pass https://localhost/api/v2;
}
location~/(?v[12]){
代理通行证https://localhost/api/$version;
}
位置/v2{
代理通行证https://localhost/api/v2;
}
如果我请求
/v2/login
,我会在regex配置中看到对
/v2
的请求,而直接匹配正确地保留了整个请求url

我尝试添加第二个捕获组,
/(?v[12])/(?*)
,然后它基本上可以工作。然而,它似乎会弄乱PUT/POST


我找不到什么解释吗?我读了,但据我所知,使用正则表达式和不使用正则表达式之间没有任何区别。

不幸的是,官方文档缺少许多重要的注释。如果您注意到Nginx有一些文档无法解释的不寻常之处,那么我建议您检查一下。在您的案例中,有趣的部分是:

一种特殊情况是在proxy_pass语句中使用变量: 请求的URL未被使用,您完全负责构建 您可以自己创建目标URL

因此,当您在
proxy\u-pass
指令中引入
$version
时,Nginx开始拒绝原始请求URI,只发送
proxy\u-pass
URI部分中的内容

这就是为什么如果您只需要涵盖两种情况(
v1
v2
),我强烈建议不要弄乱正则表达式,而是只定义两个常见前缀位置,就像您在第二个示例中所做的那样。Nginx配置不是编程代码,重复部分配置是完全正确的

但是,如果出于某种原因确实必须使用正则表达式位置,则必须重写URI:

location ~ /(?<version>v[12]) {
    rewrite ^/(.*)$ /api/$1 break;
    proxy_pass https://localhost;
}
location~/(?v[12]){
重写^/(.*)$/api/$1中断;
代理通行证https://localhost;
}
或者自己构造完整的URI:

location ~ /(?<version>v[12])(?<rest>.*)$ {
    proxy_pass https://localhost/api/$version$rest$is_args$args;
}
location~/(?v[12])(?*)${
代理通行证https://localhost/api/$version$rest$is_args$args;
}