使用变量复制 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 位置行为的主要内容,如果未能解决你的问题,请参考以下文章

在 CSS 中同时使用位置和显示的行为是啥? [复制]

Nginx proxy_pass使用$host变量

Nginx 每个位置/将重写的 uri 传递给 proxy_pass

nginx 位置 /sub/$VAR/ 到 proxy_pass /sub/$VAR/

Matlab:复制图例位置的“外部”缩放行为

为啥两个不同的简单列表变量的行为彼此完全一样? [复制]