推荐使用 django-cors-headers:先 pip install django-cors-headers,再在 INSTALLED_APPS 中添加 'corsheaders',MIDDLEWARE 中前置添加 'corsheaders.middleware.CorsMiddleware',并按需配置 CORS_ALLOWED_ORIGINS、CORS_ALLOW_CREDENTIALS 等参数。

直接用 django-cors-headers,别手写中间件或改响应头——它适配 Django 4.x(包括 4.2+),维护活跃,且能正确处理预检、凭证、正则匹配等真实场景。
安装与基础注册必须做对
错一步,整个 CORS 就不生效。常见问题不是配置漏了,而是顺序或拼写错了:
-
pip install django-cors-headers后,'corsheaders'要加进INSTALLED_APPS,位置无所谓,但不能拼成'cors-header'或漏掉s -
MIDDLEWARE中必须写全路径:'corsheaders.middleware.CorsMiddleware'(注意中间有middleware.) - 这个中间件必须排在
SecurityMiddleware、SessionMiddleware、CommonMiddleware之前——放错位置会导致响应头被后续中间件覆盖或丢弃
CORS_ALLOWED_ORIGINS 不能和 CORS_ALLOW_ALL_ORIGINS 共存
Django 4.x 的 django-cors-headers(≥4.0)会静默忽略 CORS_ALLOWED_ORIGINS,只要 CORS_ALLOW_ALL_ORIGINS = True 存在。这在生产环境等于裸奔:
- 开发时用白名单:
CORS_ALLOWED_ORIGINS = ["http://localhost:5173", "http://127.0.0.1:3000"](协议、域名、端口必须完全一致,http://localhost:3000≠http://localhost:3000/) - 需要通配符?用
CORS_ALLOW_ORIGIN_REGEXES = [r"^https://.*\.myapp\.com$"],比*安全得多 -
CORS_ALLOW_ALL_ORIGINS = True只允许出现在DEBUG = True的开发环境,CI/CD 流水线里也建议加检查脚本防误提
带 credentials 的请求必须三要素齐备
前端用了 credentials: 'include'(传 Cookie、sessionid 或 Bearer token),后端少一个条件,浏览器就静默失败,控制台只报 “CORS error”,不提示缺哪项:
立即学习“Python免费学习笔记(深入)”;
-
CORS_ALLOW_CREDENTIALS = True(必须为布尔值True,不是字符串"true") -
CORS_ALLOWED_ORIGINS显式列出源,禁用CORS_ALLOW_ALL_ORIGINS -
SESSION_COOKIE_SAMESITE = 'None'且CSRF_COOKIE_SAMESITE = 'None'(Django 4.1+ 默认是Lax,不改就发不出 Cookie) - 额外提醒:HTTPS 环境下
Samesite=None必须搭配Secure=True,所以还要设SESSION_COOKIE_SECURE = True和CSRF_COOKIE_SECURE = True
OPTIONS 预检失败多数是方法或 header 没放行
前端发 PATCH、DELETE,或带 Authorization、X-Requested-With 头时,浏览器先发 OPTIONS。如果后端没明确允许,预检就 405 或无响应:
-
CORS_ALLOW_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"](默认不含PATCH和DELETE) -
CORS_ALLOW_HEADERS = ["content-type", "authorization", "x-csrftoken", "x-requested-with"](注意小写,Django 4.x 默认只放行几个基础头) - 如果用自定义 header(如
X-Trace-ID),必须显式加进CORS_ALLOW_HEADERS,否则预检直接挂
最容易被忽略的是 SAMESITE 和 SECURE 这两个 Cookie 相关配置——它们不报错,但会让带 credentials 的跨域请求永远卡在“已发送请求,收不到响应”的状态,连 Network 面板都看不到完整响应体。


















