Nginx设置跨域,前端请求接口跨域配置示例

前言

前端页面和后端接口不在同一个域名下,浏览器报跨域错误。这是前后端分离开发最常见的问题。本文讲一下怎么用 Nginx 配置跨域。

什么是跨域

浏览器的同源策略:协议、域名、端口有一个不一样,就是跨域。

比如:

  • 前端:https://www.example.com
  • 后端接口:https://api.example.com

这两个域名不一样,浏览器就不让前端直接请求后端接口。

Nginx 配置跨域

简单配置(允许所有域名)

在接口的 server 块里加:

server {
    listen       443 ssl http2;
    server_name  api.example.com;

    # 跨域配置
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    # 处理 OPTIONS 预检请求
    if ($request_method = 'OPTIONS') {
        return 204;
    }

    root  /var/www/api;
    index index.php;
}

指定允许的域名(推荐)

生产环境不要用 *,指定具体域名更安全:

# 允许单个域名
add_header Access-Control-Allow-Origin https://www.example.com;

# 允许多个域名
set $cors_origin "";
if ($http_origin ~* "^https://(www\.example\.com|m\.example\.com)$") {
    set $cors_origin $http_origin;
}
add_header Access-Control-Allow-Origin $cors_origin;

带 Cookie 的跨域

如果跨域请求要带 Cookie,光加 * 不行:

add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;

注意: 带 Cookie 的时候,Allow-Origin 不能用 *,必须指定具体域名。

完整配置示例

server {
    listen       443 ssl http2;
    server_name  api.example.com;

    ssl_certificate      /etc/nginx/ssl/api.crt;
    ssl_certificate_key  /etc/nginx/ssl/api.key;

    # 跨域配置
    set $cors_origin "";
    if ($http_origin ~* "^https://(www\.example\.com|admin\.example\.com)$") {
        set $cors_origin $http_origin;
    }

    add_header Access-Control-Allow-Origin $cors_origin;
    add_header Access-Control-Allow-Credentials true;
    add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    # 处理 OPTIONS 预检请求
    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin $cors_origin;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
        add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
        add_header Access-Control-Max-Age 86400;
        return 204;
    }

    root  /var/www/api;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

检查配置并重载

nginx -t
nginx -s reload

常见坑

坑1:OPTIONS 请求 404

浏览器发 OPTIONS 预检请求,Nginx 直接返回 404。

原因: 没处理 OPTIONS 请求。

解决: 加上面那个 if ($request_method = 'OPTIONS') 的判断,直接返回 204。

坑2:跨域配置不生效

加了跨域配置还是报跨域错误。

原因1: PHP 后端也输出了跨域头,两边冲突了。

解决: 只留一处跨域配置,要么在 Nginx 配,要么在后端代码里配,不要两边都配。

原因2: Nginx 重载失败了。

解决: 确认 nginx -t 没问题,再 nginx -s reload。

坑3:带 Cookie 的跨域失败

配置了跨域,但是带 Cookie 请求还是失败。

原因: Allow-Origin 用了 *,浏览器不允许。

解决: 改成具体域名,加上 Access-Control-Allow-Credentials true。

坑4:POST 请求跨域失败

GET 请求没问题,POST 请求跨域了。

原因: 没允许 POST 方法或者 Content-Type 头。

解决: 把 POST 和 Content-Type 加到 Allow-Methods 和 Allow-Headers 里。

总结

配置项 作用
Access-Control-Allow-Origin 允许哪个域名访问
Access-Control-Allow-Methods 允许哪些请求方法
Access-Control-Allow-Headers 允许哪些请求头
Access-Control-Allow-Credentials 是否允许带 Cookie
Access-Control-Max-Age 预检请求缓存时间

生产环境建议: 不要用 *,指定具体域名更安全。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:26