反向代理是绕过浏览器同源策略的工程方案而非跨域解药;nginx最稳妥,需正确配置proxy_pass、三项关键header及路径前缀,避免502错误和cors冲突。

反向代理不是跨域问题的“解药”,而是绕过浏览器同源策略的常用工程方案。Nginx 是最稳妥的选择,Apache 或 Caddy 也能做,但配置逻辑和坑点不同,别混用。
为什么 Nginx 的 proxy_pass 能解决跨域,而前端直接发请求不行
浏览器对 XMLHttpRequest 和 fetch 有严格同源限制,但对页面加载的资源(如 script、img)或服务端发起的请求无此限制。Nginx 在服务端转发请求,客户端只跟 Nginx 通信,自然不触发跨域报错。
关键点:
-
proxy_pass后的地址必须写全(含协议和端口),比如http://127.0.0.1:3000,不能只写127.0.0.1:3000,否则会 502 - 后端服务必须监听在
127.0.0.1或0.0.0.0,不能只绑localhost(某些系统解析异常) - 如果后端返回了
Access-Control-Allow-Origin响应头,Nginx 默认会透传,此时可能和代理规则冲突,建议后端关掉 CORS 中间件
Nginx 配置中必须加的三项响应头
仅靠 proxy_pass 不够,浏览器仍可能因缺少必要头信息拒绝响应(尤其带凭证的请求)。以下三行要写在 location 块里:
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
说明:
-
Host头缺失会导致后端日志或路由识别出错(例如 Express 的req.hostname变成127.0.0.1) -
X-Real-IP和X-Forwarded-For决定你能否拿到真实用户 IP——没加的话,后端req.ip全是127.0.0.1 - 不要手动加
Access-Control-Allow-Origin: *到 Nginx 配置里,除非你明确不需要凭证(withCredentials: true),否则会和浏览器预检(OPTIONS)冲突
遇到 502 Bad Gateway 的常见原因和查法
502 表示 Nginx 连不上后端,不是跨域问题,别被现象误导。
排查步骤:
- 执行
curl -v http://127.0.0.1:3000/api/test,确认后端进程确实在运行且可直连 - 检查 Nginx 错误日志:
tail -f /var/log/nginx/error.log,典型报错如connect() failed (111: Connection refused) - 确认 SELinux 是否启用:
getenforce,若是Enforcing,临时关闭测试:setenforce 0 - 防火墙是否拦了本地回环通信?
sudo ufw status或firewall-cmd --list-all
前端请求路径要不要加前缀(比如 /api/)
要,而且必须和服务端暴露的路径对齐。Nginx 不会自动重写 URL 路径,除非你显式配置 rewrite。
例如后端接口是 http://localhost:3000/users,你想通过 /api/users 访问,则配置为:
location /api/ {
proxy_pass http://127.0.0.1:3000/;
}
注意末尾斜杠:
-
proxy_pass以/结尾 +location以/api/结尾 → 自动剥离/api前缀 - 若
proxy_pass不带结尾/(如http://127.0.0.1:3000),则整个/api/users会原样发给后端,导致 404 - 路径重写复杂时,优先用
proxy_redirect off;关闭自动跳转重写,避免干扰
真正容易被忽略的是后端服务的响应头和 Nginx 的缓存行为——比如后端返回了 Cache-Control: no-cache,但 Nginx 默认不缓存,实际没问题;可一旦开了 proxy_cache,就可能把错误响应也缓存住,调试时记得加 proxy_cache_bypass $http_upgrade; 临时绕过。










