Nginx位置语句在正则表达式和正常匹配中的行为不同

时间:2015-06-22 14:13:54

标签: regex nginx

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

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

location /v2 {
    proxy_pass https://localhost/api/v2;
}

如果我请求/v2/login,我会在正则表达式配置中看到/v2的请求,而直接匹配会正确保留整个请求网址。

我尝试添加第二个捕获组/(?<version>v[12])/(?<path>.*),然后它可以正常工作。但是,它似乎与PUT / POST混乱。

我缺少一些解释吗?我读了documentation,但据我所知,使用正则表达式或不使用正则表达式之间应该没有任何区别。

1 个答案:

答案 0 :(得分:2)

不幸的是,官方文档缺少许多重要的注释。如果您发现文档无法解释Nginx的异常,那么我建议您使用wiki进行检查。在你的情况下,有趣的部分是:

  

一个特例是在proxy_pass语句中使用变量:   未使用请求的URL,您完全负责构建   你自己的目标网址。

因此,只要您在$version指令中引入proxy_pass,Nginx就会开始解除原始请求URI,只发送proxy_pass URI部分中的内容。

这就是为什么如果你只需要涵盖两种情况(v1v2),我强烈建议不要乱用正则表达式而只是定义两个常见的前缀位置,就像你在你的第二个例子。 Nginx配置不是编程代码,配置的重复部分也很正常。

但是,如果由于某种原因你真的必须使用正则表达式位置,你将不得不重写你的URI:

location ~ /(?<version>v[12]) {
    rewrite ^/(.*)$ /api/$1 break;
    proxy_pass https://localhost;
}

或者自己构建完整的URI:

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