资讯专栏INFORMATION COLUMN

nginx 之 proxy_pass 接口转发的规则

jas0n / 4040人阅读

摘要:只是只是,不包含任何路径,比如这种情况下,会把匹配到的所有路径直接穿透转发。比如以下的配置访问后端结果为您的请求地址是包含路径这里的路径哪怕只是一个也是存在的,如这种情况下,里面会去掉匹配的字符串,拼接到再进行转发。

今天上了一个多页应用,发现接口转发后是 401。 最后发现是接口转发出错了。地址里多拼了一个 路径。 以前我一直以为location 字段会替换掉 proxy_pass 里面配置的 url 地址。 今天了解了一下 发现还是有不少细节的。

// node js 文件,打印请求路径。方便查看后端真实接受到的请求地址
const http = require("http");
http.createServer((req, res) => {
  console.log(req.url);
  res.end(`您的 请求 地址是${req.url}`);
}).listen(3000);

proxy_pass 如何转发,首先看 proxy_pass 的url 配置。

proxy_pass 只是HOST

proxy_pass 只是HOST,不包含任何路径,比如

* http://host - √
* https://host - √
* http://host:port - √
* https://host:port - √
* http://host/ - x
* http://host:port/ - x

这种情况下,会把匹配到的所有路径直接穿透转发。比如以下的配置

 location /api/ {
    proxy_pass http://127.0.0.1:3000;
 }

访问 http://127.0.0.1:80/api/cc, 后端结果为 您的 请求 地址是/api/cc

proxy_pass 包含路径

这里的路径哪怕只是一个 / 也是存在的,如:

http://host - x

https//host/ - √

http://host:port- x

https://host:port/ - √

http://host/api - √

http://host/api/ - √

这种情况下,url 里面会去掉 location 匹配的字符串,拼接到 proxy_pass 再进行转发。

 location /api/ {
    proxy_pass http://127.0.0.1:3000/;
 }

访问 http://127.0.0.1:81/api/cc, 后端结果为 您的 请求 地址是/cc

重写代理链接 - url rewrite

使用 rewrite 指令并且生效后,proxy_pass url 链接中的路径会被忽略,如:

server {
            listen       83;
            location / {
                rewrite ^/api/(.*) /fixpath=$1 break;
                proxy_pass http://127.0.0.1:3000/node/;
            }
            location ^/api/ {
                rewrite ^/api/(.*) /fixpath=$1 break;
                proxy_pass http://127.0.0.1:3000/node/;
            }
        }

访问 http://127.0.0.1:83/bb/cc 得到 您的 请求 地址是/node/bb/cc(匹配上 / 了,没有匹配 rewrite)
访问 http://127.0.0.1:83/api/cc 得到 您的 请求 地址是/fixpath=cc (我们写的 proxy_pass http://127.0.0.1:3000/node/ 里面的 node路径丢失了 )

知道了这几点,碰到转发接口也有一点底气啦~

更多

在github上看到的这本小书 ⬇️
(参考资料)[https://xuexb.github.io/learn...]

我的 nginx 配置

events {
}
http {
    # proxy_pass url 只是 host
    # 这时候 location 匹配的完整路径将直接透传给 url ,如:
     server {
            listen       80;
            
            location / {
                proxy_pass http://127.0.0.1:3000;
            }

            location /api/ {
                proxy_pass http://127.0.0.1:3000;
            }
           
            
        }
    # url 包含路径
    # 当 proxy_pass url 的 url 包含路径时,匹配时会根据 location 的匹配后的链接透传给 url ,注意匹配后就是这样:
     server {
            listen       81;
            
            location / {
                proxy_pass http://127.0.0.1:3000/;
            }

            location /api/ {
                proxy_pass http://127.0.0.1:3000/;
            }
            location /bpi/ {
                proxy_pass http://127.0.0.1:3000/v1;
            }
            location /cpi {
                proxy_pass http://127.0.0.1:3000/v1;
            }
        }
        # 当 location 以正则形式匹配时,proxy_pass 就不能以 / 结束了,也就是不能包含路径了, 会提示配置错误,比如错误的:

     server {
            listen       82;
            
            location / {
                proxy_pass http://127.0.0.1:3000/;
            }
        # nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /test.conf:47
        #    location ~* ^/api/ {
        #         proxy_pass http://127.0.0.1:3000/;
        #     }

        # nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /Users/tangdaoyuan/code/anheng/jz-bingjiang/test.conf:52
        #    location ~* ^/api/ {
        #         proxy_pass http://127.0.0.1:3000/b1;
        #     }
        }

    # 使用 rewrite 指令并且生效后,proxy_pass url 链接中的路径会被忽略,如:
     server {
            listen       83;
            location / {
                proxy_pass http://127.0.0.1:3000/node/;
            }
            location ^/api/ {
                rewrite ^/api/(.*) /fixpath=$1 break;
                proxy_pass http://127.0.0.1:3000/node/;
            }
        }

}

测试流程 : node 运行 服务, 启动Nginx 转发 , 再用postman 发送请求。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40604.html

相关文章

  • [手把手系列]Docker 部署 vue 项目

    摘要:部署项目写在前面作为轻量级虚拟化技术,拥有持续集成版本控制可移植性隔离性和安全性等优势。容器可以被创建启动停止删除暂停等。重新运行应用容器直接基于镜像来启动容器,运行命令将宿主机的挂载到容器的目录上。Docker 部署 vue 项目 1.写在前面: Docker 作为轻量级虚拟化技术,拥有持续集成、版本控制、可移植性、隔离性和安全性等优势。本文使用Docker来部署一个vue的前端应用,并尽...

    VPointer 评论0 收藏0
  • Nginx反向代理跨域基本配置与常见误区

    摘要:同时由于跨域了,就想利用的反向代理去处理一下跨域,但是在解决问题的同时,发现网上有些方案的确是存在一些问题,在这里总结一下基本配置,也聊一下常见的配置问题。 最近公司前后端分离,前端独立提供页面和静态服务很自然的就想到了用nginx去做静态服务器。同时由于跨域了,就想利用nginx的反向代理去处理一下跨域,但是在解决问题的同时,发现网上有些方案的确是存在一些问题,在这里总结一下基本配置...

    lindroid 评论0 收藏0
  • Nginx反向代理跨域基本配置与常见误区

    摘要:同时由于跨域了,就想利用的反向代理去处理一下跨域,但是在解决问题的同时,发现网上有些方案的确是存在一些问题,在这里总结一下基本配置,也聊一下常见的配置问题。 最近公司前后端分离,前端独立提供页面和静态服务很自然的就想到了用nginx去做静态服务器。同时由于跨域了,就想利用nginx的反向代理去处理一下跨域,但是在解决问题的同时,发现网上有些方案的确是存在一些问题,在这里总结一下基本配置...

    JasonZhang 评论0 收藏0
  • Nginx反向代理升级--upstream改造proxy_pass

    摘要:同时若不想破坏已经做好的的话,也可以不使用,直接转发到服务器的内网应该也是可以的。这样在安全和效率高上就都能得到一定的提升。 之前写了一些nginx的东西,这次继续,主要使用upstream针对proxy_pass转发做个处理一般情况下我们在使用nginx反向代理的时候,都是如下配置, ... location /api { proxy_pass https://b.test.c...

    harryhappy 评论0 收藏0
  • nginx解决跨域问题

    摘要:一产生跨域的原因浏览器限制跨域请求二解决思路解决跨域有多重,在这里主要讲用解决跨域代理浏览器禁止检查跨域三下载安装下载地址选择其中一个版本下载,再解压即可使用在目录下输入,若出现版本号,则安装成功四反向代理解决跨域客户端解决跨域我们使用的 一. 产生跨域的原因 1.浏览器限制 2.跨域 3.XHR(XMLHttpRequest)请求 二. 解决思路 解决跨域有多重,在这里主要讲用ngi...

    Jeffrrey 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<