用法/说明:

用法/说明:

带有变量的 Nginx proxy_pass 很难理解。有人能解释一下如何实现下面的场景吗?

#first call /?proxytohost=http://blahblah.com
#second redirection to /
#third call /home 

location / {
    if ($arg_proxytohost) {
        set $proxytohost $arg_proxytohost;
        rewrite ^.*$ / break;
    }

    proxy_pass https://$proxytohost;   #first call it may recognize, third call definitely it cant

    proxy_intercept_errors on;
    error_page 301 302 307 = @handle_redirects;
}

location @handle_redirects {
    set $saved_redirect_location '$upstream_http_location';
    proxy_set_header  Host $proxy_host;
    proxy_pass $proxytohost$saved_redirect_location;   #this has proxytohost, i dont think it can recognize the variable here
}

编辑:

想要反向代理几个动态实例(a.blahblah.com、b.blahblah.com 等)。每个服务实例都有多个重定向,我需要在其中存储 cookie 并重定向它们(这就是我有 @handle_redirects 部分的原因)。

$proxytohost如果我将位置声明上方的变量设置为 a.blahblah.com,那么它就会按预期工作。

但是如果我想将其$proxytohost作为动态参数发送到第一个请求,然后将其设置为变量,然后通过 proxy_pass 它,那么它就不起作用。

例如,假设我的 nginx 在 中运行localhost:8080,那么我的期望是

如果我卷曲如下

http://localhost:8080/?proxytohost=a.blahblah.com?authToken=aksdfkj

使用该令牌进行身份验证并重定向到主页后,它应该带我到主页,

http://localhost:8080/home

在这种情况下,/home是由 提供的内容https://a.blahblah.com/home

答案1

这是行不通的。

如果我理解正确的话,您希望在连续请求时代理到同一主机。Nginx 独立处理请求。因此,在第 2 次和第 3 次请求中,如果$arg_proxytohost不存在,则使用您提供的默认值。

我建议使用 Cookies。下面是一个小例子。

这需要在 http{} 中,可以在 conf.d 中的一个单独的文件中

map $cookie_p_host $p_host {
    default $cookie_p_host;
    ""      $host;
}

接下来我们有进入服务器的位置{}

location ~ /proxy/sethost/(?<p_host>.*) { 
    add_header Set-Cookie 'p_host=$p_host;path=/proxy'; 
    add_header Content-type text/html; 
    return 200 'cookie was "$cookie_p_host"<br>now set to "$p_host"'; 
}

location   ~ /proxy(?<p_uri>.*) { 
    resolver         8.8.8.8 ; 
    resolver_timeout 5s; 
    proxy_set_header Host $p_host; 
    proxy_pass       http://$p_host$p_uri; 
}

用法/说明:

映射

映射用于避免令人讨厌的 if 语句。如果设置了 cookie,它将用作主机名(无论正确与否,我们都不会检查或关心)。如果未设置(null/empty),我们将使用 $host 变量。您可以将其更改为您想要的任何内容。

第一个位置

http://localhost:8080/proxy/sethost/example.com) 将设置一个将主机设置为 example.com 的 cookie。/proxy/sethost/ 之后的任何内容都将算作主机名!

第二个地点

http://localhost:8080/proxy) 现在将代理到 example.com。如果配置中其他地方尚未添加动态查找解析器,则添加一个解析器。我们需要将代理请求的 Host 标头设置为请求的标头,然后我们就可以开始了。

希望这能有所帮助。重定向巫术是另一个话题

答案2

不使用解析器的情况下在 URL 中使用变量进行 proxy_pass 仅在 nginx-plus(商业版本)上可用

添加解析器意味着您将负责将其指向能够理解您的 URL 的 DNS。

我尝试了很长时间才让它在免费版本上运行:

proxy_pass http://$myvariable:8081;

这是 nginx 表示“付钱给我”的方式。

答案3

您可以将 if 指令更改为位置块之外,其含义相同。

if ($arg_proxytohost) {
    set $proxytohost $arg_proxytohost;
    rewrite ^.*$ / break;
}
location / {
proxy_pass https://$proxytohost;   #first call it may recognize, third call definitely it cant

proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirects;

}

相关内容