前端本地 Nginx 反向代理
一、问题引入
本地开发遇到线上bug,debug得stash代码切换分支,同时需切换开发环境与生产环境服务,npm run serve 或 npm start 费时
二、webpack-dev-server反向代理
webpack-dev-server 可以解决跨域,它基于Node代理中间件 http-proxy-middleware
配置如下
proxy: { // 需要代理的url规则 "/api": { target: "https://dev.xxx.tech", // 反向代理的目标服务 changeOrigin: true, // 开启后会虚拟一个请求头Origin pathRewrite: { "^/api": "" // 重写url,一般都用得到 } } }
补充:反向代理隐藏了真实的服务端;相反地,正向代理隐藏了真实的客户端
三、Nginx代理
1.下载Nginx
下载Nginx,选择Windows稳定版即可。
2.固定前端代理
为了避免在debug线上问题时需要切换 proxy target 而重新运行 npm start,我们在前端层把 proxy target 固定下来。比如我固定访问 127.0.0.1:8090(当然,实际上访问哪个端口可以视个人情况调整)。
proxy: { "/api": { target: "127.0.0.1:8090", // 固定代理目标 changeOrigin: true, pathRewrite: { "^/api": "" } } }
3.Nginx代理
由于前端的接口访问已经固定为 127.0.0.1:8090,我们只要在 Nginx 中监听本地 8090 端口,把请求统统转发给目标服务器即可,配置如下
server { listen 8090; server_name 127.0.0.1; location / { proxy_pass https://dev.xxx.tech; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
可以看到,在配置中注释了X-Real-IP,而在生产环境下配置 Nginx 时,一般会保留这几项Host,X-Real-IP,X-Forwarded-For,用以保留请求的服务器域名,原始客户端和代理服务器的IP等信息。
如果不注释X-Real-IP,前端访问入口的真实IP是 127.0.0.1 或 localhost,Nginx不认可这样的本地ip,直接返回404,客户端请求不予代理到其他远程服务器(这里没找到原因)。
有了以上的配置,我们就可以将前端代理层和Nginx代理层解耦,前端固定通过本地 127.0.0.1:8090 访问后端接口,而具体接口是代理到开发环境、测试环境或是生产环境,由Nginx决定,只需要修改 nginx.conf 后重启即可。
而Nginx热重启是非常快的,一条命令即可实现,几乎零等待时间。
// windows下是这个命令 nginx.exe -s reload // linux是这样的 nginx -s reload
四、本地域名
杜绝 ip 被占用这种情况,可以引入本地域名。
域名是通过解析后才能得到真实的服务IP。而域名解析过程中也有这么一些关键节点。
- 浏览器缓存
- 操作系统hosts文件
- Local DNS
- Root DNS
- gTLD Server
借用网上一张图说明下大致流程(侵删)
首先,我们找到 C:\Windows\System32\drivers\etc\hosts 这个文件,打开后在最后新增一条解析记录
127.0.0.1 www.devtest.com
然后保存这个文件,保存hosts文件时需要administrator权限。
这就相当于告诉本地操作系统,如果用户访问 www.devtest.com,我就给他解析到 127.0.0.1 这个ip
所以,我们在Nginx只要监听 127.0.0.1 的 80 端口即可,配置如下
server { listen 80; server_name 127.0.0.1; location / { proxy_pass https://dev.xxx.tech; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
最后,我们只要在前端工程中把代理目标设置为 www.devtest.com即可。
proxy: { "/api": { target: "http://www.devtest.com", // 固定代理目标 changeOrigin: true, pathRewrite: { "^/api": "" } } }
这样前端访问的某接口 http://localhost:8080/api/user/login 就会被代理到 http://www.devtest.com/user/login,而 www.devtest.com 被本地 hosts 文件解析到127.0.0.1,接着Nginx监听了127.0.0.1 的 80 端口,将请求转发到真实的后端服务。