使用变量复制 proxy_pass 位置行为
Posted
技术标签:
【中文标题】使用变量复制 proxy_pass 位置行为【英文标题】:Replicate proxy_pass location behavior with variables 【发布时间】:2021-12-22 03:42:14 【问题描述】:所以通常在创建 nginx 位置时,它看起来像这样:
location /foo/
proxy_pass http://example.com/;
通过此设置,对/foo/bar
的请求将转发到http://example.com/bar
,这是预期的行为。
但是,当尝试prevent caching of the domain name example.com
或尝试prevent nginx from crashing if the upstream host is unavailable at startup 时,唯一的解决方案似乎是不直接在proxy_pass
指令中使用目标,而是创建一个包含目标的变量,如下所示:
location /foo/
set $targetUri http://example.com/;
proxy_pass $targetUri;
但这完全改变了设置。一旦proxy_pass
包含一个变量,它就不再向目标uri 附加任何内容,正如nginx docs 描述的那样:
在 proxy_pass [...] 中使用变量时。在这种情况下,如果指令中指定了 URI,则按原样传递给服务器,替换原始请求 URI。
所以对/foo/bar
的请求被简单地转发到http://example.com/
。
当将$request_uri
加入到组合中时,会附加比我们想要的更多的内容:
location /foo/
set $targetUri http://example.com$request_uri;
proxy_pass $targetUri;
对/foo/bar
的请求现在转发到http://example.com/foo/bar
。
我发现的唯一解决方法是对该位置使用正则表达式模式:
location ~ ^/foo/(.*)$
set $targetUri http://example.com/$1$is_args$args;
proxy_pass $targetUri;
在使用变量时,有什么方法可以复制proxy_pass
的行为而无需正则表达式匹配位置?我想避免使用正则表达式的原因是位置路径基于生成位置块的用户输入。
【问题讨论】:
【参考方案1】:从$targetUri
变量中删除尾随/
,以便proxy_pass
在其值中不包含“可选URI”部分。然后使用rewrite...break
复制原始行为。
例如:
location /foo/
set $targetUri http://example.com;
rewrite ^/foo(.*)$ $1 break;
proxy_pass $targetUri;
【讨论】:
谢谢!我假设 rewrite 指令中的正则表达式模式比我在 location 块中使用正则表达式模式的解决方案的处理能力要低?以上是关于使用变量复制 proxy_pass 位置行为的主要内容,如果未能解决你的问题,请参考以下文章
Nginx 每个位置/将重写的 uri 传递给 proxy_pass