服务器跨域配置最简单方法:Nginx三步搞定前端接口报错
理解跨域:为什么前端会报错?
跨域(CORS)是浏览器基于同源策略(协议、域名、端口三者一致)自动开启的安全机制。
当你的前端网页(比如 http://a.com:8080)向另一个域名的后端接口(比如 http://b.com/api)发请求时,浏览器就会拦截响应并报错:No 'Access-Control-Allow-Origin' header。服务器跨域配置的目的就是在后端服务器(通常是 Nginx)上添加允许跨域的响应头,让浏览器放行。
本文适合以下读者:前后端联调时卡在跨域报错的新手、刚接手服务器运维想快速配置跨域的朋友,以及需要排查线上跨域问题的开发者。
读完你会掌握 Nginx 配置跨域的核心方法,并能验证配置是否生效。
准备阶段:确认服务器环境和文件位置
开始操作前,先确保你满足以下条件:
- 有一台安装了 Nginx 的服务器(CentOS、Ubuntu 均可,本文以 CentOS 7 为例)。
- 拥有服务器的 root 访问权限,或者能通过
sudo执行命令。 - 知道你的 Nginx 配置文件在哪。默认路径:
/etc/nginx/nginx.conf或/etc/nginx/conf.d/下的.conf文件。如果你用宝塔面板,可在后台“网站” -> 设置 -> 配置文件 处编辑。 - 如果你还没有 Nginx,先执行安装:
sudo yum install nginx -y(CentOS)或sudo apt update && sudo apt install nginx -y(Ubuntu)。
核心操作:在 Nginx 中添加跨域配置
打开你的 Nginx 配置文件(以编辑 /etc/nginx/conf.d/your-site.conf 为例),在 location / 或对应的接口路径块内添加如下配置。
如果你的后端接口统一走 /api/ 路径,就在 location /api/ 块中修改。
server {
listen 80;
server_name your-domain.com;
location /api/ {
# 允许所有来源跨域(生产环境建议替换为具体前端域名)
add_header Access-Control-Allow-Origin *;
# 允许的请求方法
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
# 允许的请求头
add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
# 预检请求(OPTIONS)缓存时间,单位秒
add_header Access-Control-Max-Age 1728000;
# 单独处理 OPTIONS 预检请求,直接返回 204
if ($request_method = 'OPTIONS') {
return 204;
}
# 这里放你的反向代理配置(如果有)
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
配置说明:
Access-Control-Allow-Origin:指定允许跨域的域名。生产环境建议写具体域名(如https://frontend.com),不要用*,否则不安全。OPTIONS请求是浏览器在发送实际跨域请求前发起的预检请求,需要单独返回204并结束处理,否则浏览器会报“预检请求失败”。Access-Control-Max-Age可选,用于减少重复预检请求。
如果你的 Nginx 只做静态文件服务器,
没有代理后端,
直接在 server 块内添加跨域头即可,
但要注意 add_header 在 location 内会继承,
除非你指定了 always 参数。
避坑指南:最易出错的三个点
- OPTIONS 请求未正确处理:这是新手最常忽略的地方。很多教程只加了
add_header,但没有单独返回204,导致浏览器预检失败。必须用if ($request_method = 'OPTIONS')返回 204。 - add_header 作用域:
add_header指令只在当前块内生效。如果你在server层配置,但location内有自己的add_header,浏览器可能收到多个重复头,甚至覆盖。建议统一在需要跨域的location内配置。 - CORS 头缺少 Allow-Headers:前端可能携带自定义 Header(如
Authorization或X-Requested-With),必须在Access-Control-Allow-Headers中显式声明。如果漏掉,浏览器会报Request header field Authorization is not allowed by Access-Control-Allow-Headers。
额外提醒:如果配置后仍报跨域,先刷新浏览器缓存(部分浏览器会缓存预检结果),再检查响应头是否真的携带了配置的头。
效果验证:如何确认跨域配置生效
完成配置后,执行以下步骤验证:
步骤1:重载 Nginx
sudo nginx -t # 测试配置语法
sudo systemctl reload nginx # 或 nginx -s reload
确保没有报错。
步骤2:使用 curl 模拟跨域请求
直接在服务器或本地终端执行:
curl -H "Origin: http://example.com" -I http://your-server-domain/api/xxx
查看返回的头部,是否包含 Access-Control-Allow-Origin: *(或你配置的域名)。
如果出现,说明配置成功。
步骤3:浏览器开发者工具测试
打开前端页面,按 F12 进入 Network 面板,刷新页面,找到对应的接口请求。如果 Response Headers 中包含 Access-Control-Allow-Origin 且 console 没有跨域报错,即代表配置生效。
高频问题解答:
- Q:为什么我加了配置还是报跨域?
A:检查是否忘记重载 Nginx;
确认配置块是作用在接口路径上;
查看浏览器 Network 响应头是否为空,如果为空可能是请求没到达 Nginx(比如请求被前端 mock 拦截)。
- Q:多个前端域名如何配置?
A:Nginx 不支持直接写多个域名,可以通过 map 指令或 if 判断动态允许。
也可以直接写 *,但安全性低。
更推荐做法:如果前端域名固定,直接写具体域名;
如果允许所有子域名,用 add_header Access-Control-Allow-Origin "$http_origin"; 并配合 Access-Control-Allow-Credentials true; 以及 if 校验。
- Q:配置后接口能访问但 cookie 丢失?
A:
如果需要携带 cookie(凭证),Access-Control-Allow-Origin 不能为 *,
必须写具体域名,
并且加上 add_header Access-Control-Allow-Credentials true;。
如果你当前正在处理跨域配置,建议先按本文步骤在你的测试环境验证,确认没问题再应用到生产。
跨域配置本身不复杂,但细节容易踩坑,希望这份指南能帮你一次搞定。