You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法配置NGINX处理CORS跨域请求,请求排查问题原因

解决CORS预检请求失败问题:你的NGINX配置和前端代码问题分析

一、NGINX配置中的核心问题

  1. 缺失关键CORS响应头
    你的HTTPS(443端口)server块里完全没加Access-Control-Allow-Origin头,这是CORS验证的核心响应头,必须添加。另外你重复写了两次Access-Control-Allow-Methods "*",属于冗余操作,删掉一个即可。

  2. 配置语法错误
    配置里有一行include /etc/l,明显是不完整的路径(应该是Certbot生成的include /etc/letsencrypt/options-ssl-nginx.conf;),语法错误会导致NGINX无法正确加载配置,所有自定义头的设置都不会生效。

  3. 未处理OPTIONS预检请求
    你的前端请求带了X-Requested-With自定义头,浏览器会先发送OPTIONS预检请求验证权限,但当前配置没有专门处理OPTIONS请求,需要添加对应的location块返回预检所需的头。

  4. HTTP(80端口)配置无效
    80端口的server块里,add_header指令放在if块外面,但当if块触发301跳转时,这些头不会被携带;而且HTTP跳转的CORS头对HTTPS的API请求没有意义,无需在80端口配置CORS。

二、前端代码中的问题

前端请求里设置了xmlhttp.setRequestHeader('Access-Control-Allow-Origin', '*');,这是完全错误的——Access-Control-Allow-Origin是后端返回的响应头,不是前端发送的请求头,添加这个请求头不仅没用,还可能干扰预检逻辑,必须删掉。


修复后的NGINX配置

server {
    server_name api.example.com;
    index file.json;

    location / {
        root /var/www/example/html;
        default_type application/json;
        add_header Content-Type application/json;
        # 核心CORS头,允许前端域名跨域,建议指定具体域名而非*(如果需要带Cookie的话)
        add_header Access-Control-Allow-Origin "https://www.example.com";
        add_header Access-Control-Allow-Methods "*";
        # 允许自定义请求头,包含你前端用的X-Requested-With
        add_header Access-Control-Allow-Headers "X-Requested-With, Content-Type";
    }

    # 专门处理OPTIONS预检请求
    location / {
        if ($request_method = OPTIONS) {
            add_header Access-Control-Allow-Origin "https://www.example.com";
            add_header Access-Control-Allow-Methods "*";
            add_header Access-Control-Allow-Headers "X-Requested-With, Content-Type";
            # 预检请求的缓存时间,减少重复OPTIONS请求
            add_header Access-Control-Max-Age 3600;
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            return 204;
        }
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # managed by Certbot
    # 补全Certbot的include指令
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    listen 80;
    server_name api.example.com;
    # 直接跳转到HTTPS,无需CORS头
    return 301 https://$host$request_uri;
}

修复后的前端代码

var xmlhttp = new XMLHttpRequest();
var url = "https://api.example.com";

xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var myArr = JSON.parse(this.responseText);
        console.log(myArr);
    }
};
xmlhttp.open("GET", url, true);
xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
// 删掉错误的Access-Control-Allow-Origin请求头
xmlhttp.send();

额外说明

  • 如果你不需要携带Cookie,Access-Control-Allow-Origin可以用*,但建议指定具体的前端域名(https://www.example.com),更安全。
  • 修改NGINX配置后,记得执行sudo nginx -t验证配置语法,然后sudo systemctl reload nginx重启服务生效。

内容的提问来源于stack exchange,提问作者兄弟鏈

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 01:44:56