主题
Nginx 反向代理
一、Nginx 的三大职责
- 静态资源托管:前端构建产物的 Web 服务器。
- 反向代理:
/api请求转发给后端,隐藏内部端口。 - HTTPS + 反向代理 + 负载均衡:生产入口的标准组件。
用户 → 80/443(Nginx)
├── / → 前端静态文件(Vue/React 页面)
├── /assets/* → 前端静态资源
└── /api/* → 后端 http://127.0.0.1:8080二、前端容器内的 nginx.conf
前端 Dockerfile 里已经 COPY 了一个 nginx 配置,实现 SPA 路由和 /api 转发:
nginx
# web-vue/nginx.conf
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# 静态资源缓存
location /assets/ {
expires 7d;
add_header Cache-Control "public";
}
# SPA 路由:前端路由刷新不 404
location / {
try_files $uri $uri/ /index.html;
}
# API 反向代理到后端
location /api/ {
proxy_pass http://server:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}SPA 路由为什么必须 try_files
Vue/React 是单页应用,路由在前端。用户刷新 https://mall.com/order/list 时,Nginx 找不到 /order/list 这个文件,必须回退到 index.html 让前端路由接管。漏了这一行,刷新页面就 404。
三、生产服务器上的 Nginx(宿主机)
上线时更常见的做法:前端构建产物直接放服务器,由宿主机 Nginx 托管 + 反向代理到容器内的后端:
nginx
# /etc/nginx/conf.d/mall.conf
server {
listen 80;
server_name mall.example.com;
# 前端静态文件
root /var/www/mall-web;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8080; # 后端容器映射到 8080
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}bash
sudo nginx -t # 检查配置语法
sudo systemctl reload nginx # 平滑重载,不中断服务四、HTTPS:Let's Encrypt 免费证书
bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d mall.example.comCertbot 会自动:
- 申请证书
- 改写 Nginx 配置加
listen 443 ssl - 配置 HTTP → HTTPS 跳转
- 设置定时自动续期(证书 90 天有效期)
生成后的配置(certbot 自动生成,了解即可):
nginx
server {
listen 443 ssl http2;
server_name mall.example.com;
ssl_certificate /etc/letsencrypt/live/mall.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mall.example.com/privkey.pem;
# 其余同 http 配置...
}
server { # HTTP 自动跳 HTTPS
listen 80;
server_name mall.example.com;
return 301 https://$host$request_uri;
}五、验证 HTTPS
bash
curl -I https://mall.example.com # 看 200 和证书
curl -I http://mall.example.com # 301 跳转浏览器访问确认地址栏出现小锁。
混合内容问题
页面已 HTTPS,但里面请求 http://api 会被浏览器拦截。生产环境前端构建时 VITE_API_BASE 要用 https:// 前缀,保证全站 HTTPS。
六、本章验收
- [ ] 前端刷新
/order/list不 404(SPA 路由正确) - [ ]
https://域名/api/product/list能返回数据 - [ ] HTTP 访问自动跳转 HTTPS
- [ ] 浏览器地址栏有小锁,无混合内容警告