proxy_pass使用内置变量报错

2020-02-26  本文已影响0人  刀斧手何在

缘起

前两天有同学提到个问题:有一个域名a.fangle.com 下uri携带指定参数的路由转发到b.fangle.com 这个域名的app模块下。请求要达到的效果大概是这样的:

http://a.fangle.com/test/index.php?r=tools/Translator&volume=50
=> 
http://b.fangle.com/app/test/index.php?r=tools/Translator&volume=50

nginx 配置大概如下:

events {
    worker_connections 1024;
}

http {
    include a.conf;
    include b.conf;
}
server {
    listen 80;
    server_name a.fangle.com;
 
    location ~\.php$ {
        if ($args ~ r=tools\/Translator) {  
           proxy_pass http://b.fangle.com/app?$request_uri;
           break;
        }
    }

    access_log  logs/a.access.log;
    error_log  logs/a.error.log;
}
server {

    server_name b.fangle.com;
    listen 80;

    location / {
        echo "b.com";
        echo $uri;
        echo $request_uri;
        echo "b.end";
    }

    access_log  logs/b.access.log;
    error_log  logs/b.error.log;
}

but 一直502 ,于是我就过来玩了一把。


image.png

proxy_pass

我们找到error_log

2020/02/22 23:19:10 [error] 20274#149076: *57 no resolver defined to resolve b.fangle.com, client: 127.0.0.1, server: a.fangle.com, request: "GET /test/index.php?r=tools/Translator&volume=50 HTTP/1.1", host: "a.fangle.com"

这是因为proxypass使用了nginx变量,会自动做域名反向解析。
解决方法:

 resolver 127.0.0.1;

重启发现报了一个新错

2020/02/22 23:22:05 [error] 20342#150105: *59 b.fangle.com could not be resolved (3: Host not found), client: 127.0.0.1, server: a.fangle.com, request: "GET /test/index.php?r=tools/Translator&volume=50 HTTP/1.1", host: "a.fangle.com"

开启本机的dns服务后:


image.png

重写uri

当然你可能会说,我能不能不要resolve。我看你就是想为难我胖虎。
其实也是可以的,proxy_pass 如果不指定uri的时候,nginx会自动带上当前的uri

if ($args ~ r=tools\/Translator) {   
        proxy_pass http://b.fangle.com/app$request_uri;
 }
image.png

但是这个地址reqest_uri不是我们想要的,so我们还是要重写以下uri才能使用
放弃这种想法

if ($args ~ r=tools\/Translator) {   
       set $request_uri "/app${request_uri}"; 
        proxy_pass http://b.fangle.com;
 }

nginx内置变量不允许修改

利用rewrite重写

set $proxy_pass_b false;
location ~\.php$ { 
        if ($args ~ r=tools\/Translator) {  
            set $proxy_pass_b true; 
            rewrite ^(.*)$ /app$request_uri? last;
        }
 }

location /app {
    #echo $request_uri;
    #echo $args;
        
    if ($proxy_pass_b = true) {
          proxy_pass http://b.fangle.com;
    }
}
image.png

利用openresty 重写

待测试

如果允许域名发生变化,也可以考虑使用return or rewirte

return

return 是nginx最简单的转发方式

 if ($args ~ r=tools\/Translator) {  
       return 301 http://b.fangle.com/app?$request_uri;
 }

效果:


image.png

rewrite

if ($args ~ r=tools\/Translator) {   
            rewrite ^(.*)$ http://b.fangle.com/app$uri last;
 }

效果同return


image.png

rewrite 和 return 没有本质上的区别,当然这种情况常用return,因为语义更清晰。rewirte 常用于url重写,就是server内部跳转,效率更高


参考阅读

上一篇 下一篇

猜你喜欢

热点阅读