服务器 > 服务器 > Linux

nginx跨域访问配置的几种方法实现

11人参与 2025-12-08 Linux

一、基本跨域配置

在 nginx 的 location 块中添加以下内容:

location /api/ {
    add_header 'access-control-allow-origin' '*' always;
    add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
    add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
 
    # 处理预检请求(options)
    if ($request_method = 'options') {
        add_header 'access-control-max-age' 1728000;
        add_header 'content-type' 'text/plain charset=utf-8';
        add_header 'content-length' 0;
        return 204;
    }
 
    # 其他反向代理/静态资源配置...
    proxy_pass http://backend-server;
}

说明:

二、只允许指定域名跨域

如果只允许某个域(如 https://www.example.com)跨域:

add_header 'access-control-allow-origin' 'https://www.example.com' always; 

三、完整示例

假设你有一个前端(端口 8080)和后端(端口 8000),nginx 代理 /api/ 到后端:

server {
    listen 80;
    server_name your.domain.com;
 
    location /api/ {
        proxy_pass http://127.0.0.1:8000;
        add_header 'access-control-allow-origin' '*' always;
        add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
        add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
 
        if ($request_method = 'options') {
            add_header 'access-control-max-age' 1728000;
            add_header 'content-type' 'text/plain charset=utf-8';
            add_header 'content-length' 0;
            return 204;
        }
    }
}

四、配置后重载 nginx

每次修改配置后,记得重载 nginx:

nginx -s reload 

五、注意事项

六、支持携带 cookie 的跨域配置

如果你需要前端跨域请求时携带 cookie(如登录态),cors 需要特殊配置:

  1. access-control-allow-origin 不能为 *,必须指定具体的域名。
  2. 需要加上 access-control-allow-credentials: true

示例:

location /api/ {
    proxy_pass http://127.0.0.1:8000;
 
    add_header 'access-control-allow-origin' 'https://www.example.com' always;
    add_header 'access-control-allow-credentials' 'true' always;
    add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
    add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
 
    if ($request_method = 'options') {
        add_header 'access-control-max-age' 1728000;
        add_header 'content-type' 'text/plain charset=utf-8';
        add_header 'content-length' 0;
        return 204;
    }
}

前端请求时需要设置:

fetch('https://api.example.com/api/', {
  credentials: 'include', // 允许携带 cookie
  // 其他参数
})

七、根据请求头动态设置允许的 origin

有时你希望根据请求头 origin 动态设置允许的域名,可以用 nginx 的变量:

location /api/ {
    proxy_pass http://127.0.0.1:8000;
 
    if ($http_origin ~* "^https://(www\.example\.com|other\.domain\.com)$") {
        add_header 'access-control-allow-origin' "$http_origin" always;
        add_header 'access-control-allow-credentials' 'true' always;
    }
 
    add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
    add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
 
    # 处理预检请求
    if ($request_method = 'options') {
        add_header 'access-control-max-age' 1728000;
        add_header 'content-type' 'text/plain charset=utf-8';
        add_header 'content-length' 0;
        return 204;
    }
}

八、常见问题排查

  1. add_header 不生效?

    • 确认 always 关键字已加上。
    • 确认没有被其他配置覆盖。
    • 确认 location 块没有被其他 server/location 块覆盖。
  2. options 请求未返回 204?

    • 检查 if 语句是否正确。
    • 检查是否被后端拦截。
  3. 前端报错:cors header ‘access-control-allow-origin’ missing?

    • 检查响应头是否包含该字段。
    • 用浏览器开发者工具 network 检查响应头。
  4. 携带 cookie 时跨域失败?

    • 确认 access-control-allow-origin 不是 *,而是具体域名。
    • 确认 access-control-allow-credentials: true 已设置。
    • 前端 fetch/axios 需配置 credentials。

九、nginx 跨域配置模板(推荐)

可以将以下内容作为通用模板:

location /api/ {
    proxy_pass http://backend-server;
 
    # 支持跨域
    set $cors '';
    if ($http_origin ~* '^https://(www\.example\.com|other\.domain\.com)$') {
        set $cors 'true';
    }
 
    if ($cors = 'true') {
        add_header 'access-control-allow-origin' "$http_origin" always;
        add_header 'access-control-allow-credentials' 'true' always;
    }
 
    add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
    add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
 
    # 预检处理
    if ($request_method = 'options') {
        add_header 'access-control-max-age' 1728000;
        add_header 'content-type' 'text/plain charset=utf-8';
        add_header 'content-length' 0;
        return 204;
    }
}

十、针对不同路径/接口做跨域控制

有时你只希望对部分接口(如 /api/)开放跨域,对其他接口(如 /admin/)不开放,可以这样配置:

server {
    listen 80;
    server_name your.domain.com;
 
    # 只对 /api/ 开放跨域
    location /api/ {
        proxy_pass http://backend-api;
        add_header 'access-control-allow-origin' '*' always;
        add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
        add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
 
        if ($request_method = 'options') {
            add_header 'access-control-max-age' 1728000;
            add_header 'content-type' 'text/plain charset=utf-8';
            add_header 'content-length' 0;
            return 204;
        }
    }
 
    # /admin/ 不开放跨域
    location /admin/ {
        proxy_pass http://backend-admin;
        # 不添加跨域相关 header
    }
}

十一、静态资源跨域(如图片、字体、js/css)

如果你希望静态资源(如图片、字体文件等)可以被其他域引用,需为静态资源 location 添加 cors 响应头:

location /static/ {
    root /var/www/html;
    add_header 'access-control-allow-origin' '*' always;
    add_header 'access-control-allow-methods' 'get, options' always;
    add_header 'access-control-allow-headers' 'origin, content-type, accept' always;
}

注意:如果你希望字体文件可被第三方引用,必须加上 access-control-allow-origin,否则会有跨域问题。

十二、根据请求方法细分 cors 策略

有时你希望 get/post/put/delete 允许跨域,而 patch 不允许,可以这样写:

location /api/ {
    proxy_pass http://backend-server;
 
    if ($request_method ~* "get|post|put|delete|options") {
        add_header 'access-control-allow-origin' '*' always;
        add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
        add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
    }
 
    if ($request_method = 'options') {
        add_header 'access-control-max-age' 1728000;
        add_header 'content-type' 'text/plain charset=utf-8';
        add_header 'content-length' 0;
        return 204;
    }
}

十三、反向代理多后端的跨域配置

如果 nginx 代理多个后端(如 /api1//api2/),每个后端都需要跨域:

location /api1/ {
    proxy_pass http://backend1;
    add_header 'access-control-allow-origin' '*' always;
    # ...同上
}
 
location /api2/ {
    proxy_pass http://backend2;
    add_header 'access-control-allow-origin' '*' always;
    # ...同上
}

十四、nginx 1.7.5 及以上版本的 always 参数

确保你用的 nginx 版本支持 always 参数,否则有些 header 在 4xx/5xx 状态下不会返回。

十五、安全建议

  1. 生产环境不要使用 *,要指定具体域名。
  2. 不建议在 / 根路径全局添加 cors,容易引发安全隐患。
  3. 如需支持多域名跨域,推荐用变量和正则动态判断。
  4. 如果接口涉及敏感数据,务必开启认证和 https。

十六、调试技巧

十七、完整多场景配置模板

server {
    listen 80;
    server_name your.domain.com;
 
    # 静态资源
    location /static/ {
        root /var/www/html;
        add_header 'access-control-allow-origin' '*' always;
    }
 
    # api1 跨域
    location /api1/ {
        proxy_pass http://backend1;
        add_header 'access-control-allow-origin' 'https://www.a.com' always;
        add_header 'access-control-allow-credentials' 'true' always;
        add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
        add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
        if ($request_method = 'options') {
            add_header 'access-control-max-age' 1728000;
            add_header 'content-type' 'text/plain charset=utf-8';
            add_header 'content-length' 0;
            return 204;
        }
    }
 
    # api2 跨域
    location /api2/ {
        proxy_pass http://backend2;
        add_header 'access-control-allow-origin' 'https://www.b.com' always;
        add_header 'access-control-allow-methods' 'get, post, options, put, delete' always;
        add_header 'access-control-allow-headers' 'origin, content-type, accept, authorization' always;
        if ($request_method = 'options') {
            add_header 'access-control-max-age' 1728000;
            add_header 'content-type' 'text/plain charset=utf-8';
            add_header 'content-length' 0;
            return 204;
        }
    }
}

到此这篇关于nginx跨域访问配置的几种方法实现的文章就介绍到这了,更多相关nginx跨域访问配置内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

Nginx服务器部署详细代码实例

12-08

Nginx 访问控制的多种方法

12-08

Linux安装Redis以及Redis三种启动实现过程

12-08

查看Linux版本信息的四种常用方法

12-08

Linux中实现文件复制与迁移的命令详解

12-08

Linux环境下监控和检查内存使用的几种方法

12-08

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论