前端在 localhost:5173 调试,接口部署在另一个域名,浏览器控制台甩出一行 Access-Control-Allow-Origin 相关的红字,请求状态显示 CORS error。后端不想改代码,最省事的办法是在 nginx 上加响应头。
跨域是浏览器的同源策略在拦,协议、域名、端口有一个不同就算跨域。nginx 把请求转发给后端时,顺手补上 CORS 响应头,浏览器就放行。
一份能用的配置
location /api/ { add_header Access-Control-Allow-Origin https://www.example.com always; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS always; add_header Access-Control-Allow-Headers Content-Type,Authorization always; if ($request_method = OPTIONS) { return 204; } proxy_pass http://127.0.0.1:8080; }三个容易踩的坑
第一,带 Cookie 的请求不能用星号,Origin 必须写具体域名,同时加 Access-Control-Allow-Credentials true。第二,add_header 默认只对 200、204、301 这些状态码生效,后面加 always 才稳。第三,location 里再写 add_header 会覆盖上层的,别在两层重复配置。
预检请求 OPTIONS 要直接返回 204,别转发给后端,否则后端没处理就会 405。响应里再加 Access-Control-Max-Age 86400,浏览器能把预检结果缓存一天,少发不少请求。
改完执行 nginx -t 再 reload,用 curl -I 看一下响应头有没有带上,比反复刷新页面快。多个前端域名要放行时,可以用 map 根据请求头里的 Origin 返回对应值,别偷懒写死一个。
另外,CORS 是浏览器端的限制,不是服务端鉴权,接口该做的登录校验和权限控制一样不能少。