当涉及到多个令牌号时,我遇到了一些重写问题。
我正在对我们的API进行版本控制,因此不推荐使用的版本调用将转到我们的最新版本。为了简单起见,我们假设我们支持v4和v5。当一些数据命中我们的v1-3时,我们需要它转到v5。同样,如果有人点击v6,它也应该转到v5。
我们的nginx.conf使用proxy_pass和upstream,所以我让每个版本在不同的端口上运行
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;
}最后一个location块适用于v0-9,但当数字是多位数(如v11 )时,即使我使用的是+,它也无法捕获。
这方面的任何帮助都是很好的。对此真的很迷惑。谢谢!
发布于 2016-12-11 19:41:42
在下面的块中:
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 (有关location语法,请参阅this document )。
我添加了一个last后缀,以使rewrite的意图变得清晰。
编辑:回复您的评论
仅使用前缀/块来区分URI、/v5和/v51 (即没有尾随的/)是有问题的。如果URI 总是(至少)在版本字符串之后有一个尾随/,那么只需将一个尾随/添加到您现有的两个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;
}请注意,修饰符被更改为~*,这引入了一个正则表达式(并使其不区分大小写-这对您来说可能很重要,也可能不重要)。
https://stackoverflow.com/questions/41083781
复制相似问题