Nginx配置通用反向代理指定域名到指定服务

前言

首先我们先看一下要达到的效果,我们希望访问某一个域名自动指向本地启动的某一个端口的服务(我们就以域名 <number>.localapp.com 为例),效果如下:

ini 复制代码
8080.localapp.com => 127.0.0.1:8080
8081.localapp.com => 127.0.0.1:8081

接下来大家可能会说为什么要这么做呢,直接访问 http://127.0.0.1:8080 不好吗,非得转一层呢?下面就是好处:

1、解决 cookie 共享的问题

我们直接访问 http://127.0.0.1:8080 是拿不到 localapp.com 下面的 cookie 的,有部分网站的授权是通过 cookie 实现的,当然这个也可以通过 本地配置 host + webpack proxy 实现,但是需要在每个项目中都这样配置。

2、解决跨域的问题

在前后端分离的开发模式中,一般情况前端和服务端一般会使用不同域名。假如 localapp-api.com 这个是接口服务器域名,这个服务只允许 *.localapp.com 域名访问时,我们就只能通过 本地配置 host + webpack proxy 中的方式去配置,同样在每个项目都需要修改。如果项目中使用到了 OSS 并且开启了防盗链,OSS 也会去校验域名,导致 OSS 中的资源会加载失败。

3、配置本地 https 证书

如果使用 http://127.0.0.1:8080 访问,是不好配置 https 证书的,访问的时候也就会出现证书错误警告,首先是对开发不友好,如果我们想在手机端有些 app 的 webview 调试页面,那必须要用 https,如果配置了证书,就可以方便的调试。还有一点大家可能发现了,http 服务是拿不到 https 服务下面的 cookie 的。

4、同时启动多个项目

如果我们通过 本地配置 host + webpack proxy 来解决上面的问题,那我们必须要将服务在80或者443上启动,所以无法同时调试多个项目。

实施方案

下面内容主要包含如下:

  • 搭建本地的 DNS 服务器,进行域名解析,将 <number>.localapp.com 指向 127.0.0.1
  • 配置配置 nginx 反向代理实现域名指向指定端口

运行流程如下

搭建DNS服务器

首先我们要知道为什么要搭建 DNS 服务器呢,而不是直接将域名指向 hosts 呢?是因为 hosts 文件不支持通配符,那么每个端口就需要写一条记录,添加了新的端口就需要添加新的记录,如下:

yaml 复制代码
127.0.0.1 8080.localapp.com
127.0.0.1 8081.localapp.com
127.0.0.1 8082.localapp.com
127.0.0.1 8083.localapp.com

这里我们使用 dnsmasq 来搭建 DNS 服务器,该软件可以运行在 linux/macOS 等操作系统上,以 macOS 为例,我们可以直接使用 brew 进行安装(linux 可以使用内置的 apt 或者 yum 工具进行安装)。

bash 复制代码
brew install dnsmasq

安装完成修改配置添加 DNS 解析规则,配置文件位置在 $HOMEBREW_PREFIX/etc/dnsmasq.conf ,我们可以使用 VSCode 或者 vim 进行修改。

要添加上面的解析,需要在配置文件中追加下面的内容,这条内容表示 .localapp.com 都解析到 127.0.0.1 ,当然这里也可以指向局域网的其他 IP 实现解析。

bash 复制代码
# 如果仅仅给自己使用的话,就用 127.0.0.1,否则的话可以加上局域网的IP地址,使用逗号分开
listen-address=127.0.0.1,192.168.1.6
# 注意下面的规则仅匹配 abc.localapp.com 不能匹配,abc.def.localapp.com
address=/.localapp.com/127.0.0.1

修改完成之后,重新启动一下 DNS 服务器即可;

bash 复制代码
# 这里要使用sudo,否则可能会不生效,不加sudo执行时,控制台也会给出警告
sudo brew services restart dnsmasq

配置DNS解析

DNS 服务器搭建完成之后,我们还需要修改下本地网络 DNS 解析,以 macOS 为例:

需要将 127.0.0.1 这个 DNS 放到第一位,保存网络后,在本地终端 ping 的时候就会发现下面的域名都指向了 127.0.0.1。

ping 123.localapp.com
ping 456.localapp.com
ping abc.localapp.com

配置反向代理

1、首先我们在 nginx 中创建一个配置文件如 proxy.localapp.conf ,然后将 server_name 设置为正则表达式,具体内容如下所示:

nginx 复制代码
server {
    listen 80;
    server_name ~^(?<port>\d+)\.localapp\.com$;
    location / {
        # 代理到本地的端口上
        # 8000.local.com => 127.0.0.1:8000
        # 9000.local.com => 127.0.0.1:9000
        proxy_pass http://127.0.0.1:$port;
        proxy_set_header Host $host;
        client_max_body_size 50m;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass_header Sec-Websocket-Extensions;
        index index.html index.htm;
    }
}

配置说明:

  • server_name: 该域名匹配 1~n 个数字开头的域名,并且将这段数字提取后存储在变量 port 中,例如 8080.localapp.com 中 port=8080。
  • proxy_pass: 直接转发到本地127.0.0.1监听的某一个端口号上。
  • proxy_set_header: 设置代理请求的头信息,用于真实的目标服务器一些 header。例如设置了 Host 为 $host,在 http://127.0.0.1:8080 这台服务器中得到的 Host 就是 8080.localapp.com 而不是 127.0.0.1:8080。

2、重新加载 Nginx 配置以使更改生效

bash 复制代码
nginx -s reload

测试

现在在 8080 端口上启动一个 webpack devServer,然后使用 8080.localapp.com 去访问发现就可以正常使用了。

常见问题

1、要是发现配置的 dns 无效,可以检查是否开启了 clash,需要把域名规则在 clash 中排除

相关推荐
ᥬ 小月亮2 分钟前
Js前端模块化规范及其产品
开发语言·前端·javascript
码小瑞17 分钟前
某些iphone手机录音获取流stream延迟问题 以及 录音一次第二次不录音问题
前端·javascript·vue.js
SomeB1oody19 分钟前
【Rust自学】7.4. use关键字 Pt.2 :重导入与换国内镜像源教程
开发语言·后端·rust
weixin_18919 分钟前
‌Vite和Webpack区别 及 优劣势
前端·webpack·vue·vite
半吊子伯爵20 分钟前
开发过程优化·自定义鼠标右键菜单
前端·javascript·自定义鼠标右键菜单
新知图书24 分钟前
Rust编程与项目实战-箱
开发语言·后端·rust
xcLeigh24 分钟前
HTML5实现好看的喜庆圣诞节网站源码
前端·html·html5
SomeB1oody28 分钟前
【Rust自学】7.3. use关键字 Pt.1:use的使用与as关键字
开发语言·后端·rust
minstbe37 分钟前
WEB开发 - Flask 入门:Jinja2 模板语法进阶 Python
后端·python·flask
Tirzano42 分钟前
vue3 ts 简单动态表单 和表格
前端·javascript·vue.js