1. 解决前端开发中的跨域问题
1.1 场景说明
• 问题:前端应用运行在 http://localhost:3000
,需请求 https://api.example.com
,但浏览器因CORS策略阻止请求。
• 解决方案:通过Nginx正向代理将API请求转发到目标服务器,绕过浏览器同源限制。
1.2 Nginx正向代理配置
# /etc/nginx/conf.d/frontend-proxy.conf
server {
listen 8080;
resolver 8.8.8.8; # 必须配置DNS解析
# 代理所有API请求到目标服务器
location /api/ {
proxy_pass https://api.example.com/; # 目标API地址
proxy_set_header Host api.example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 禁用缓存以便实时调试
proxy_buffering off;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
}
1.3 前端代码调用
// 将请求路径改为代理服务器地址
fetch('http://localhost:8080/api/data')
.then(response => response.json())
.then(data => console.log(data));
2. 结合现代前端工具链
2.1 使用Vite/Webpack代理(开发服务器内置代理)
• Vite配置(vite.config.js
):
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:8080', // 指向Nginx代理
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}
• 说明:Vite开发服务器将 /api
请求转发到Nginx代理,再由Nginx转发到真实API。
2.2 直接使用Nginx代理(复杂场景)
• 适用场景:
• 需要同时代理多个API服务。
• 需模拟生产环境请求路径。
• 配置示例:
location /external-api/ {
proxy_pass https://external-service.com/;
}
location /internal-api/ {
proxy_pass http://localhost:5000/;
}
3. 模拟生产环境请求路径
3.1 保持路径一致性
• 目标:开发环境与生产环境的API路径一致(如 /api/users
)。
• Nginx配置:
server {
listen 80;
server_name local.example.com; # 本地域名
location /api/ {
proxy_pass http://localhost:8080/api/; # 指向Nginx正向代理
}
}
• 前端调用:直接使用 http://local.example.com/api/data
。
3.2 修改本地Hosts文件
# /etc/hosts(Linux/macOS)
127.0.0.1 local.example.com
4. 处理HTTPS和WebSocket
4.1 HTTPS代理配置
server {
listen 8080;
resolver 8.8.8.8;
# 启用HTTPS代理支持(需ngx_http_proxy_connect_module模块)
proxy_connect;
proxy_connect_allow 443;
proxy_connect_connect_timeout 10s;
location / {
proxy_pass https://$http_host$request_uri;
proxy_set_header Host $http_host;
}
}
4.2 WebSocket代理
location /ws/ {
proxy_pass http://backend-server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
5. 安全增强措施
5.1 IP白名单限制
location /api/ {
allow 127.0.0.1; # 仅允许本地访问
allow 192.168.1.0/24; # 允许内网
deny all;
proxy_pass https://api.example.com/;
}
5.2 基本认证
location /api/ {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass https://api.example.com/;
}
• 生成密码文件:
printf "username:$(openssl passwd -crypt password)\n" >> /etc/nginx/.htpasswd
6. 调试与验证
6.1 查看请求头信息
# 使用curl测试代理
curl -v http://localhost:8080/api/data
• 检查响应头中的 X-Proxy-By: Nginx
(可自定义添加)。
6.2 日志监控
log_format proxy_log '$remote_addr - $upstream_addr [$time_local] "$request"';
access_log /var/log/nginx/proxy-access.log proxy_log;
7. 性能优化(可选)
7.1 缓存静态资源
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m inactive=60m;
location /api/static/ {
proxy_cache api_cache;
proxy_pass https://api.example.com/static/;
proxy_cache_valid 200 304 12h;
}
7.2 连接池优化
upstream api_backend {
server api.example.com:443;
keepalive 32; # 复用TCP连接
}
location /api/ {
proxy_pass https://api_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
8. 完整配置示例
# 开发环境正向代理 + 前端服务
server {
listen 80;
server_name local.example.com;
# 前端静态资源
location / {
root /path/to/frontend/dist;
index index.html;
}
# 代理API请求
location /api/ {
proxy_pass https://api.example.com/;
proxy_set_header Host api.example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
}
# WebSocket代理
location /ws/ {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
9. 工具与生态整合
工具 | 作用 | 配置示例 |
---|---|---|
Postman | 测试代理接口 | 设置代理:http://localhost:8080 |
Charles | 抓包调试 | 匹配代理规则到Nginx |
Docker | 容器化部署代理环境 | 挂载Nginx配置到容器 |
Jenkins | 自动化部署代理配置 | 使用Pipeline脚本更新Nginx |