美文网首页
proxy_pass使用内置变量报错

proxy_pass使用内置变量报错

作者: 刀斧手何在 | 来源:发表于2020-02-26 00:53 被阅读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 配置大概如下:

  • nginx.conf
events {
    worker_connections 1024;
}

http {
    include a.conf;
    include b.conf;
}
  • a.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;
}
  • b.conf
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变量,会自动做域名反向解析。
解决方法:

  • a.conf 的location 中添加
 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

  • a.conf
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最简单的转发方式

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

效果:


image.png

rewrite

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

效果同return


image.png

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


参考阅读

相关文章

  • proxy_pass使用内置变量报错

    缘起 前两天有同学提到个问题:有一个域名a.fangle.com 下uri携带指定参数的路由转发到b.fangle...

  • 获取ip的函数

    使用获取环境变量的内置函数:getenv();

  • Python3笔记

    dict取值防止报错 使用d['k']取值,如果不存在名为k的键会直接报错,防止报错可使用dict内置的get(k...

  • varnish变量

    VCL 内置公共变量 VCL 内置的公共变量可以用在不同的 VCL 函数中,下面根据使用的不同阶段进行介绍 当请求...

  • Jmeter 之 BeanShell实战

    一、操作变量通过使用BeanShell内置对象vars可以对变量进行存取操作a) vars.get("name")...

  • Nginx之配置

    一个简单的配置文件如下: 1、 内置变量 在log_format配置项当中,使用了很多Nginx的内置变量,一些变...

  • 接口测试---mock变量自定义变量的使用

    接口测试的时候会使用随机的变量,apipost内置有mock变量和全局变量,还支持在脚本中使用mock.js进行自...

  • Go-Think

    1.元组赋值 2. 未使用的变量以及包编译报错 Go中定义了未使用的局部变量或者导入了未使用的包,编译时都会报错 ...

  • 青铜到王者 ,快速提升你 Go语言的段位! "狗&

    1 变量定义 变量一旦定义了,就必须使用到,否则报错 总结

  • Kotlin学习1

    1声明变量和内置数据类型 2只读变量 要声明可修改变量,使用var关键字要声明只读变量,使用val关键字 val ...

网友评论

      本文标题:proxy_pass使用内置变量报错

      本文链接:https://www.haomeiwen.com/subject/tfhcchtx.html