CORS错误只在前端调用时出现是因为浏览器同源策略限制,Django本地访问正常;需正确配置django-cors-headers中间件顺序、CORS_ALLOWED_ORIGINS白名单(含协议端口)、凭据支持及Nginx头透传。

为什么 CORS 错误只在前端调用 API 时出现,Django 本地访问却正常?
因为浏览器强制执行同源策略,而 Django 开发服务器(http://127.0.0.1:8000)和前端(比如 http://localhost:3000)端口不同,就被当成跨域——Django 默认不发 Access-Control-Allow-Origin 响应头,浏览器直接拦掉响应,连后端日志都看不到请求记录。
- 这不是 Django 路由或视图的问题,加
@csrf_exempt或改ALLOWED_HOSTS都没用 - 前端用
fetch或axios发请求时,预检请求(OPTIONS)失败,控制台报错类似:Response to preflight request doesn't pass access control check - 开发环境常见组合:React/Vue 前端跑在
localhost:3000,Django 后端在127.0.0.1:8000,必须显式放行
安装 django-cors-headers 后,为什么还是 403 或白屏?
装完包不等于生效,关键在中间件顺序和白名单配置。它必须放在 django.middleware.common.CommonMiddleware 之后、但要在所有可能拦截响应的中间件(如 SecurityMiddleware)之前。
- 检查
MIDDLEWARE列表:'corsheaders.middleware.CorsMiddleware'必须在'django.middleware.common.CommonMiddleware'下方,且不能在'django.middleware.security.SecurityMiddleware'上方 -
CORS_ALLOWED_ORIGINS必须是完整协议 + 域名 + 端口,例如:['http://localhost:3000', 'http://127.0.0.1:5173'];写成localhost(缺协议)或http://localhost(缺端口)都会被拒绝 - 开发阶段别开
CORS_ALLOW_ALL_ORIGINS = True,它会忽略白名单,但生产环境绝对禁用——某些安全中间件会与之冲突,导致 403
CORS_ALLOWED_ORIGINS 和 CORS_ALLOW_ALL_ORIGINS 怎么选?
前者精确控制,后者粗暴放行,但后者在 Django 4.0+ 中默认禁用凭据支持,且和 CSRF_COOKIE_SECURE 等设置有隐式冲突。
- 开发用
CORS_ALLOWED_ORIGINS更稳妥,支持带端口、多域名,例如:['http://localhost:3000', 'https://staging.example.com'] - 如果前端需要带 cookie 登录(比如
withCredentials: true),必须同时设CORS_ALLOW_CREDENTIALS = True,且CORS_ALLOWED_ORIGINS不能为*—— 浏览器明确禁止通配符 + 凭据共存 -
CORS_ALLOW_ALL_ORIGINS = True在调试时看似方便,但一旦开启SESSION_COOKIE_SAMESITE = 'Lax'或启用了 HTTPS 强制,就容易触发静默失败
Django 4.2+ 部署到 Nginx 后,CORS 头突然没了?
Nginx 默认不透传响应头,即使 Django 正确返回了 Access-Control-Allow-Origin,Nginx 也可能把它过滤掉,尤其用了 proxy_pass 但没配头转发规则。
- 在 Nginx 的
location块里加这几行: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' 'Content-Type, Authorization, X-Requested-With' always;
- 特别注意
always参数——没有它,Nginx 对 304 或错误响应不会加这些头,导致 OPTIONS 预检失败 - 如果 Nginx 做了缓存,确认没缓存 OPTIONS 请求,否则预检可能被缓存响应误导
CORS_ALLOW_ALL_ORIGINS 导致凭据失效。










