直接用django-cors-headers即可,因其已覆盖99%场景,能正确处理预检请求、凭证传递及header白名单;手动加响应头会漏掉凭证限制、options处理、多头控制及中间件顺序等关键环节。

直接用 django-cors-headers,别自己手写中间件或响应头 —— 它已覆盖 99% 的真实场景,且能正确处理预检(OPTIONS)请求、凭证传递、Header 白名单等细节。
为什么不能只改 Access-Control-Allow-Origin: * 响应头?
手动在视图里加响应头看似简单,但会漏掉关键环节:
- 浏览器对带凭证(如 Cookie、Authorization)的请求,拒绝接受
*作为Access-Control-Allow-Origin值,必须写具体域名; - 非简单请求(如
PUT、DELETE、Content-Type: application/json)会先发OPTIONS预检,你得单独写一个视图处理它,否则 405 或 403; - 你没法统一控制
Access-Control-Allow-Headers、Access-Control-Expose-Headers、Access-Control-Max-Age等字段,前端调用fetch()时容易报错; - 中间件顺序错误会导致 CORS 头根本不出现在最终响应里(比如
CorsMiddleware放在CommonMiddleware后面)。
CORS_ALLOW_ALL_ORIGINS=True 能不能直接开?
开发环境可以,生产环境绝对不行 —— 这等于把 API 暴露给任意网站,包括钓鱼页。更安全的做法是显式声明白名单:
- 开发时写:
CORS_ALLOWED_ORIGINS = ["http://localhost:8080", "http://127.0.0.1:3000"]; - 测试/预发环境用正则:
CORS_ALLOW_ORIGIN_REGEXES = [r"^https://\w+\.mycompany\.com$"]; - 如果前端是静态托管(如 Vercel/Netlify),确保域名完整带
https://,不带尾部斜杠; - 注意:
CORS_ALLOW_ALL_ORIGINS和CORS_ALLOWED_ORIGINS互斥,同时设会引发警告甚至失效。
带 Cookie 或 Token 的请求总失败?检查这三点
前端发请求时加了 credentials: 'include',后端却报 “The value of the 'Access-Control-Allow-Origin' header must not be the wildcard '*'”,说明配置没对齐:
- 必须设
CORS_ALLOW_CREDENTIALS = True(默认是False); -
CORS_ALLOWED_ORIGINS不能为*,必须是精确匹配的完整协议+域名+端口; - Django 的
CSRF_COOKIE_SAMESITE和SESSION_COOKIE_SAMESITE得设成'None',否则 Cookie 不会随跨域请求发送 —— 并且要配SECURE_COOKIE = True(生产环境 HTTPS 下才允许Samesite=None)。
最常被忽略的是中间件顺序和 CORS_ALLOW_CREDENTIALS 与白名单的联动。哪怕其他都对,只要 CorsMiddleware 没放在 MIDDLEWARE 最前面,或者开了凭证却还用 * 允许源,前端就必然卡在预检或响应头校验上。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











