Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Map Or Rewrite】Nginx基于会话转发的一些实践

【Map Or Rewrite】Nginx基于会话转发的一些实践

原创
作者头像
于顾而言SASE
发布于 2025-06-10 01:35:59
发布于 2025-06-10 01:35:59
8400
代码可运行
举报
文章被收录于专栏:golang与云原生golang与云原生
运行总次数:0
代码可运行

谜题

朋友们,又到了解题时间,假设有这么一个场景,现在我们有一个Nginx网关作为公网暴露面,用于代理内网的web服务,本身配置如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
http {
      server {
        listen       8080;
        server_name  localhost;

        access_log  logs/host.access.log;

         location / { 
            root   html;
            index index.html index.htm; 
            try_files $uri $uri/ /index.html;
         }
      }
}

也就是说原来的Nginx网关,有一个所有请求默认入口,所有localhost:8080的请求,都兜底转发到这里。灰常简单的配置,现在有一个新需求了,小明有一个管理平台,假设地址是http://192.168.134.35:18080/,也想通过这个Nginx进行代理,但为了业务区分,Nginx网关需要新增一个local前缀,也就是类似这样的配置,这样以来就不会干扰其他业务了,OA,ERP啥的用不同前缀区分,但公网的域名还是一个:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
http {
      server {
        listen       8080;
        server_name  localhost;

        access_log  logs/host.access.log;

         location / { 
            root   html;
            index index.html index.htm; 
            try_files $uri $uri/ /index.html;
         }
         
         # TODO
         location ^~ /xiaoming/ {
            # TODO 
        }
      }
}

但其实这个方案是不行的,因为除了第一个请求会显式带http://localhost:8080/xiaoming/外,剩余的js请求可能是不带的,因为会存在js硬编码的情况,让我举个例子,慢慢分析。

1. 环境准备

为了使例子更加真实,我下载了一个github上star很多的管理平台vue-pure-admin

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
docker pull freddyshen/vue-pure-admin:latest

docker run -dp 18080:80  --name pure-admin  freddyshen/vue-pure-admin:latest

# 打开页面 http://192.168.134.35:18080/

可以看出,功能都有很全了。好了,我们现在要代理这个网站,并且要以前缀的形式http://localhost:8080/xiaoming/

2. 方案一:rewrite+跳转

我们直接配置为这样的Nginx配置看看可不可以:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
http {
      server {
        listen       8080;
        server_name  localhost;

        access_log  logs/host.access.log;

         location / { 
            root   html;
            index index.html index.htm; 
            try_files $uri $uri/ /index.html;
         }
         
         location ^~ /xiaoming/ {
             proxy_pass http://192.168.134.35:18080/;
             proxy_set_header Host $host;
        }
      }
}

我开启一个无痕窗口和wireshark抓包,然后输入反代的地址:http://127.0.0.1:8080/xiaoming/

发现无法加载起来,抓包可以看出,除了第一个请求,其余请求都没有带这个xiaoming的前缀,这样导致路由不到了:

所以,我们的直觉就是需要让他后续加上这个前缀,那么就是在每个响应的报文中,把他的接口地址给改了,比如他的第一个index.html返回的是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
... ...
    <script type="module" crossorigin src="/static/js/index-Hy0LnPHS.js"></script>
    <link rel="stylesheet" crossorigin href="/static/css/index-C0mLDhWK.css">
    <link rel="stylesheet" href="/assets/layout-theme-light.css" id="theme-link-tag">
  </head>
   ... ...

通过ngnix rewrite功能给他给改了,sub_filter关键字可以对reponse的内容进行简单的字符串替换

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
location ^~ /xiaoming/ {
     proxy_pass http://192.168.134.35:18080/;
     proxy_set_header Host $host;
     proxy_redirect http://$host/ http://$host/xiaoming/;

     sub_filter_once off;
     sub_filter_types application/json text/javascript;
     sub_filter 'src="/'  'src="/xiaoming/';
     sub_filter 'href="/' 'href="/xiaoming/';
}

好滴,我们继续打开代理页面:

oh no依然不行,我们查看抓包和Nginx error log可以清楚的看到问题所在:

其余都改了,为啥有一个特立独行的呢?我逐一查看响应包就会发现,他是一个js中请求的一个url:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
er({method:"get",url:`${qPe}platform-config.json`}).then(({data:t})=>{let n=e.config.globalProperties.$config;return e&&n&&typeof t=="object"&&(n=Object.assign(n,t),e.config.globalProperties.$config=n,YPe(n)),n}).catch(()=>{throw"public platform-config.json"})}),Sl=()=>u5().ResponsiveStorageNameSpace,

这种情况就不好通过subfilter rewrite了,风险很大,我们不知道哪里有url。我们虽然可以用跳转的方式比如,他请求的不是/xiaoming开头的,我就自动302给他跳转到/xiaoming,这样虽然可以解决,但是这个Nginx只能给xiaoming独享了,后面假设有别的业务/xiaohong就不行了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
location / {
      # xiaoming独享了,xiaohong该怎么办
      if ($request_uri !~ ^/xiaoming/) {
          rewrite ^/(.*)$ /xiaoming/$1 permanent; 
      }
      
      proxy_pass http://192.168.134.35:18080/;
      proxy_set_header Host $host;
  }

  location ^~ /xiaoming/ {
       proxy_pass http://192.168.134.35:18080/;
       proxy_set_header Host $host;
       proxy_redirect http://$host/ http://$host/xiaoming/;

       sub_filter_once off;
       sub_filter_types application/json text/javascript;
       sub_filter 'src="/' 'src="/xiaoming/';
       sub_filter 'href="/' 'href="/xiaoming/';
  }

  # xiaohong该怎么办
  location ^~ /xiaohong
  }

3. 方案二:cookie+map

所以,我们自然想到能不能基于客户请求的会话进行转发,比如他请求http://127.0.0.1:8080/xiaoming/时,这个第一个请求给他打上标签,接着所有后续请求客户都带上这个标签,这样我基于这个标签就行转发,就按这个思路走:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
map $cookie_jwt  $proxy_tag { 
    default        "off";  
    ~^eyJ  "xiaoming_tag";
}

  server {
  ... ...
  
    location / {
        if ($proxy_tag = "xiaoming_tag") {
            proxy_pass http://192.168.134.35:18080;
        }
        root   html;
        index index.html index.htm; 
        try_files $uri $uri/ /index.html;
    }
    
    location ^~ /xiaoming/ {
        root   html;
        index  index.html index.htm;
        
        proxy_pass http://192.168.134.35:18080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        add_header Set-Cookie "jwt=eyJhbGciOi; Path=/; HttpOnly";
    }

... ... 
    
}

我来解释一下这个配置,第一个请求http://127.0.0.1:8080/xiaoming/时,会匹配location ^~ /xiaoming/,此时Nginx会主动告诉客户端后续cookie要带上jwt=eyJhbGciOi,这样后续请求有这个cookie时,会首先命中map关键字,如果coockie包含eyJ,则给我自定义的变量proxy_tag赋值为xiaoming_tag,这样后续即使请求不带xiaoming的前缀,匹配到默认的location /时,也会根据if ($proxy_tag = "xiaoming_tag")来正确转发到后端。

4. Reference

https://nginx.org/en/docs/http/converting_rewrite_rules.html

https://nginx.org/en/docs/http/

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
nginx常用配置
proxy_redirect 该指令用来修改被代理服务器返回的响应头中的Location头域和“refresh”头域。
章工运维
2023/05/19
9700
我所有在线项目的Nginx配置内容
有几个小伙伴想看看我的Nginx是怎么配置的,我这里放出来吧。 其实没太多内容,都是基本的配置: 1、域名的代理(正向/反向); 2、IP地址获取; 3、SingleR Header配置; 4、前后端配置; 5、域名配置; 6、HTTPS配置; 7、负载配置; #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.
老张的哲学
2022/04/11
5630
通过nginx转发WebSocket
通过nginx请求websocket的时候需要修改配置文件,对于websocket请求需要特殊处理一下,需要在conf配置文件中添加一些配置:
全栈程序员站长
2022/11/02
2.6K0
Nginx 路由转发和反向代理 location 配置「建议收藏」
"^~":用于标准uri前,要求Nginx找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,而不再使用location块中的正则uri和请求字符串做匹配
全栈程序员站长
2022/11/02
21K0
Nginx 常用的基础配置(web前端相关方面)
最近很多朋友通过趣站网问到Nginx配置前端 web 服务,所以特地写了这篇文章;希望能够帮助更多的朋友。
趣站网
2023/02/07
1.5K0
Nginx 常用的基础配置(web前端相关方面)
手把手教你玩转 Nginx 配置
在现代的互联网应用中,Nginx 已经成为了不可或缺的组成部分。无论是作为静态资源服务器、反向代理服务器、还是负载均衡器,Nginx 的高性能和灵活配置都让它备受青睐。
南山竹
2024/07/03
1.5K0
手把手教你玩转 Nginx 配置
后端开发人员必备的一份NGINX学习清单
作为一名服务端研发工程师,接触服务器的时间也比较多。在项目对外提供服务,我们一般会使用NGINX来提供对外的服务,因此NGINX的操作也非常多,这就需要我们对NGINX比较熟悉,因此特意整理了一份相对完善的清单。
兔云小新LM
2024/06/29
2120
Nginx多站点设置及负载均衡
apache端口88 tomcat端口8080
似水的流年
2018/01/14
2.3K0
【随手记】Nginx配置详解
Nginx 是一个高性能的 HTTP 服务器和反向代理,它以其稳定性、丰富的功能集、简单的配置和低资源消耗而闻名。Nginx主要用来处理HTTP请求,提供负载均衡、静态内容服务、反向代理等功能。
客怎眠qvq
2024/04/26
4.4K0
【随手记】Nginx配置详解
Nginx反向代理负载均衡配置梳理大全
利用ngx_http_core_module、ngx_http_rewrite_module模块 主要是301跳转 Return写法:域名http请求跳转到对应的https请求
三杯水Plus
2018/11/14
8200
Nginx 常用实践
Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。性能是 Nginx 最重要的考量,其占用内存少、并发能力强、能支持高达 5w 个并发连接数,最重要的是,Nginx 是免费的并可以商业化,配置使用也比较简单。
默存
2023/09/01
3630
Nginx 常用实践
Nginx location匹配规则
上述配置,默认访问/会重定向到/my-module, 然后直接返回/data/my-module/dist下的html等静态文件。
Ryan-Miao
2019/06/18
2K0
【Nginx】Nginx部署实战——静态文件+反向代理+均衡负载+Https+Websocket
Nginx是一款是由俄罗斯的程序设计师Igor Sysoev所开发高性能的 Web和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。前一段时间听说Igor Sysoev被俄罗斯警方带走了,不知道放出来了没有。言归正常,来看一下nginx的相关配置如何满足我们的日常需求吧。
DDGarfield
2022/06/23
2.5K0
nginx负载均衡(5种方式)、rewrite重写规则及多server反代配置梳理
Nginx除了可以用作web服务器外,他还可以用来做高性能的反向代理服务器,它能提供稳定高效的负载均衡解决方案。nginx可以用轮询、IP哈希、URL哈希等方式调度后端服务器,同时也能提供健康检查功能。目前有众多公司均已经部署使用nginx实现基于七层的负载均衡功能。 1)Nginx负载均衡 为了实现Nginx的反向代理以及负载均衡功能,应用中需要用到两个模块,HttpProxyModule和HttpUpstreamModule模块;其中HttpProxyModule模块的作用是将用户的数据请求转发到其他服
洗尽了浮华
2018/01/23
8.2K0
nginx负载均衡(5种方式)、rewrite重写规则及多server反代配置梳理
Nginx配置反向代理 java服务和前端服务
终有链响
2024/07/29
3130
Nginx 配置
在了解具体的Nginx配置项之前我们需要对于Nginx配置文件的构成有所概念,一般来说,Nginx配置文件会由如下几个部分构成:
一滴水的眼泪
2020/09/24
1.9K0
Nginx配置多端口多域名访问
在一个服务器上部署多个站点,需要开放多个端口来访问不同的站点,流程很简单,调试花了2小时,记录一下:
happy123.me
2019/12/30
11.1K0
Linux环境 使用Docker部署Vue项目
1.无法通过路由请求页面,报nginx404,参考default.conf文件的配置
果冻程序
2024/06/05
4030
Linux环境 使用Docker部署Vue项目
Nginx配置文件nginx.conf全解
nginx配置文件nginx.conf的配置http、upstream、server、location等;
青山师
2023/05/05
8050
Nginx的https配置记录以及http强制跳转到https的方法梳理
一、Nginx安装(略) 安装的时候需要注意加上 --with-http_ssl_module,因为http_ssl_module不属于Nginx的基本模块。 Nginx安装方法: # ./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module # make && make install 二、生成证书(略) 可以使用openssl生成证书
洗尽了浮华
2018/01/23
5.9K0
相关推荐
nginx常用配置
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档