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

React前端+Django后端跨域问题:Access-Control-Allow-Origin多值错误

解决React+Django架构的CORS跨域错误

错误核心原因

浏览器提示Access-Control-Allow-Origin头包含多个值,说明至少有两个来源在返回这个头——要么是你以为关闭的Django仍在输出CORS头,要么是Nginx配置里重复添加了该头,同时请求跳转(3xx)导致两次返回头叠加。

分步解决步骤

1. 彻底确认Django的CORS功能已关闭

  • 卸载django-cors-headers包(如果之前安装过):
    pip uninstall django-cors-headers
    
  • 检查Django的settings.py,确保以下内容被移除或注释:
    # INSTALLED_APPS 里的 'corsheaders'
    # MIDDLEWARE 里的 'corsheaders.middleware.CorsMiddleware'
    # 所有以CORS_开头的配置项(比如CORS_ALLOW_ALL_ORIGINS等)
    
  • 重启Django后端服务。

2. 修复Nginx的API服务配置(关键)

你的api.sitename.com配置存在两个严重问题:

  • 核心请求路径/未代理到Django后端(proxy_pass被注释),导致/documents请求无法正确路由到后端,触发不必要的跳转。
  • 用if指令添加CORS头(Nginx的if存在逻辑陷阱,容易导致重复添加)。

修改后的api.sitename.com的server块如下:

server {
    server_name api.sitename.com;
    listen 80;
    server_tokens off;
    client_max_body_size 10m;
    root /var/html/;

    # 统一处理所有API请求,代理到Django后端
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_pass http://backend:8000;

        # 统一配置CORS头,避免重复
        # 若前端不需要带Cookie,可替换为 '*'
        add_header Access-Control-Allow-Origin "http://www.sitename.com" always;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, HEAD" always;
        add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
        add_header Access-Control-Expose-Headers "Content-Length,Content-Range" always;

        # 直接响应OPTIONS预检请求
        if ($request_method = OPTIONS) {
            return 204;
        }
    }

    # 保留原有的静态资源和admin配置
    location /media/ {
        autoindex on;
    }

    location /docs/ {
        root /usr/share/nginx/html;
        try_files $uri $uri/redoc.html;
    }

    location /static/rest_framework/ {
        autoindex on;
    }

    location /static/admin/ {
         autoindex on;
    }

    # 原/admin/代理可保留,或合并到上面的/代理中
    location /admin/ {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_pass http://backend:8000/admin/;
    }
}

3. 验证配置并重启服务

  • 检查Nginx配置语法:
    nginx -t
    
  • 重启Nginx生效:
    systemctl restart nginx
    
  • 用curl测试CORS头是否唯一:
    curl -I -H "Origin: http://www.sitename.com" http://api.sitename.com/documents/15/
    
    查看返回头中Access-Control-Allow-Origin是否只有一个值(要么是指定的域名,要么是*)。

4. 处理跳转问题

如果仍出现跳转提示,检查:

  • Django的settings.py中APPEND_SLASH是否为True(默认是),确保请求路径末尾带斜杠。
  • Nginx的proxy_pass末尾是否带斜杠:若后端路由不带前缀,用proxy_pass http://backend:8000;(不带斜杠),避免路径拼接错误。

内容的提问来源于stack exchange,提问作者Саша Асеев

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:22:56