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

Nginx反向代理Django时CORS预请求报错求助

解决CORS策略错误:请求头access-control-allow-origin不被允许

问题情况

使用Nginx部署React静态文件,Waitress运行Django REST Framework(API服务地址0.0.0.0:8000),Nginx作为Django的反向代理。已开启Django的全源允许,Nginx配置中添加了跨域请求头和预请求头,但仍收到以下错误:

“Access to XMLHttpRequest at 'http://15.295.156.60:8000/core/profile/profile/' from origin 'http://15.295.156.60' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.”

已尝试操作:

  • 修改Nginx配置,为反向代理添加跨域和预请求头
  • 修改Django设置,允许所有源

当前配置

Django配置

CORS_ALLOW_ALL_ORIGINS = True

CORS_ORIGIN_WHITELIST = [
'http://192.168.56.1:80',
'http://localhost:3000',
'http://*',
# Add any other origins that you want to allow here
]

前端Axios请求代码

const axiosInstance = axios.create({
baseURL: baseURL,
timeout: 5000,
headers: {
    Authorization: localStorage.getItem('access_token')
        ? 'JWT ' + localStorage.getItem('access_token')
        : null,
    'Content-Type': 'application/json',
    accept: 'application/json',
}, 
});

Nginx反向代理配置

location / {
        root   "C:/Users/Administrator/Desktop/build";
        try_files $uri $uri/ /index.html;
    }

    location /core/ { 
        # Handle preflight requests (OPTIONS)
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' * always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Content-Length' 0;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            return 204;
        }
        add_header 'Access-Control-Allow-Origin' * always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        
        proxy_pass http://15.295.156.60:8000;
    }

问题根源与修复方案

1. 错误核心原因

  • 报错提示access-control-allow-origin不被允许,说明预请求响应的Access-Control-Allow-Headers未覆盖前端实际发送的请求头(比如你的前端里有accept头,但Nginx配置里没加)。
  • CORS_ORIGIN_WHITELIST中的http://*是无效配置,Django不支持通配符,且已开启CORS_ALLOW_ALL_ORIGINS = True,这个白名单完全多余。
  • Nginx同时设置Access-Control-Allow-Origin: *和Access-Control-Allow-Credentials: true是冲突的——带凭证的跨域请求不允许用通配符作为允许源。

2. 分步修复

步骤1:清理Django CORS配置

保留核心配置即可,删除无效的白名单:

CORS_ALLOW_ALL_ORIGINS = True
# 若需要带Cookie等凭证,保留下面一行;不需要则删除
# CORS_ALLOW_CREDENTIALS = True

步骤2:修正Nginx跨域配置

  • 把通配符*替换为具体的前端源http://15.295.156.60(如果需要凭证),或者删除Access-Control-Allow-Credentials(不需要凭证时)。
  • 在Access-Control-Allow-Headers中添加前端实际发送的accept头,确保覆盖所有请求头。
  • 添加代理头传递真实请求信息给Django。

修改后的Nginx配置示例:

location / {
        root   "C:/Users/Administrator/Desktop/build";
        try_files $uri $uri/ /index.html;
    }

    location /core/ { 
        # 处理预请求
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' 'http://15.295.156.60' always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
            # 包含所有前端发送的请求头
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, accept' always;
            # 带凭证时保留,否则删除
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Content-Length' 0;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            return 204;
        }
        add_header 'Access-Control-Allow-Origin' 'http://15.295.156.60' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, accept' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        
        proxy_pass http://15.295.156.60:8000;
        # 传递真实请求信息给Django
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

步骤3:检查前端请求

确认前端没有错误将access-control-allow-origin作为请求头发送(你的Axios代码目前没有这个问题,可检查全局拦截器是否有额外添加)。

步骤4:重启服务

  • 重启Django服务
  • 重启Nginx服务,确保配置生效

内容的提问来源于stack exchange,提问作者Parameshwar Kumawath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:13:19