Nginx是本地开发前后端分离项目时最稳妥的跨域代理方案,通过反向代理使前后端同源(如均走http://localhost),天然规避CORS限制,且复用线上配置、不依赖后端改码或浏览器插件。

本地开发时用 localhost 调前端、后端分离项目,浏览器报 CORS 错误 是常态。Nginx 是最稳妥的跨域代理方案——它不依赖后端改代码,也不靠浏览器插件“作弊”,适合真实还原生产环境的请求链路。
为什么推荐 Nginx 代理而不是其他方式
前端直接调 http://localhost:3000 → http://localhost:8000/api,本质是两个不同端口,浏览器视为跨域。常见替代方案有:
- 前端用
proxy(如 vite.config.ts 中的server.proxy):只对开发服务器生效,无法覆盖所有请求(比如 iframe、fetch with credentials),且上线即失效; - 后端加 CORS 头(
Access-Control-Allow-Origin: *):开发环境可快速验证,但涉及凭证(cookie/token)时需配credentials: true,而*不兼容,必须写死 origin,本地多端口难维护; - 禁用浏览器安全策略(如 Chrome 启动参数):危险、不可持续、团队协作不现实。
Nginx 在中间层做反向代理,让浏览器认为前后端同源(例如都走 http://localhost/),天然绕过跨域检查,还能复用线上配置逻辑。
基础 Nginx 配置:把 /api 代理到后端服务
假设后端运行在 http://127.0.0.1:8000,前端静态资源放在 /path/to/dist,希望访问 http://localhost/ 加载页面,http://localhost/api/xxx 转发给后端:
server {
listen 80;
server_name localhost;
<pre class="brush:php;toolbar:false;"># 前端静态资源
location / {
root /path/to/dist;
try_files $uri $uri/ /index.html;
}
# API 接口代理
location /api/ {
proxy_pass http://127.0.0.1:8000/;
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 X-Forwarded-Proto $scheme;
}}
注意:proxy_pass 结尾的 / 很关键——它会剥离 /api/ 前缀再转发。例如请求 /api/users,实际发给后端的是 /users。若后端接口本就带 /api 前缀,此处应去掉 proxy_pass 末尾的 /,并用 rewrite 控制路径。
处理带 Cookie 的跨域请求(登录态保持)
如果前端调登录接口后需携带 cookie 访问后续 API,光代理不够,还要显式开启凭证支持:
- 前端 fetch 必须加
credentials: 'include'; - Nginx 配置中增加:
proxy_cookie_path / "/; SameSite=None; Secure";(仅 HTTPS 环境需Secure,本地 HTTP 可省略); - 后端响应头需含:
Access-Control-Allow-Credentials: true和明确的Access-Control-Allow-Origin(不能为*),例如http://localhost; - Nginx 可补全缺失的 CORS 头(如果后端没配):
add_header 'Access-Control-Allow-Origin' 'http://localhost';<br> add_header 'Access-Control-Allow-Credentials' 'true';<br> add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';<br> add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
⚠️ 注意:预检请求(OPTIONS)需被正确响应。Nginx 可直接返回 204:
location /api/ {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin 'http://localhost';
add_header Access-Control-Allow-Credentials 'true';
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE';
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header Access-Control-Max-Age 86400;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
proxy_pass http://127.0.0.1:8000/;
# ... 其他 proxy_* 配置
}
调试技巧与常见坑
- Nginx 配置修改后必须 reload(
nginx -s reload),不是 restart; - 确认前端请求地址已改为
/api/xxx(而非http://localhost:8000/api/xxx),否则仍跨域; - 用浏览器开发者工具的 Network 面板看请求的 Protocol 列:显示
http/1.1或h2说明走的是 Nginx;若显示ws或直接连后端端口,说明代理未生效; - 遇到 502 Bad Gateway:先
curl http://127.0.0.1:8000/health确认后端是否真在运行;再检查proxy_pass地址是否可通(Nginx 运行用户是否有权限访问该地址); - Mac 用户若用 Homebrew 安装 Nginx,默认配置在
/opt/homebrew/etc/nginx/nginx.conf,别改错文件。
不复杂但容易忽略。











