cors错误是浏览器同源策略拦截所致,需安装django-cors-headers并正确配置:将'corsheaders'加入installed_apps,'corsmiddleware'置于commonmiddleware之前、sessionmiddleware之后,且必须设置cors_allowed_origins白名单(如['https://www.php.cn/link/8e5687e2d6ab87e5da2f833f3e8986a4'])。

直接装 djangorestframework-simplejwt 不能解决 CORS 报错,真正要装的是 django-cors-headers,且必须配置中间件顺序和白名单。
为什么浏览器报 Access to fetch at 'http://localhost:8000/api/login/' from origin 'https://www.php.cn/link/8e5687e2d6ab87e5da2f833f3e8986a4' has been blocked by CORS policy
这是浏览器的同源策略拦截,不是 Django 报错,也不是 API 返回了错误状态码。Django 默认不发 Access-Control-Allow-Origin 响应头,前端发请求时预检(OPTIONS)失败或响应头缺失,浏览器就静默拒绝响应体。
常见误操作:
- 只在视图里手动加
response["Access-Control-Allow-Origin"] = "*"—— 不处理 OPTIONS 请求,也不支持凭证(cookies) - 用 Nginx 反向代理但没配
add_header,以为后端不用管 - 装了
django-cors-headers却漏掉CorsMiddleware或位置放错
如何正确安装并启用 django-cors-headers
执行 pip install django-cors-headers 后,必须做三件事:
- 把
'corsheaders'加到INSTALLED_APPS最前面(避免被其他 app 覆盖信号) - 把
'corsheaders.middleware.CorsMiddleware'插入MIDDLEWARE,位置必须在CommonMiddleware之前、AuthenticationMiddleware之后(否则 session 和 token 验证可能失效) - 至少设置一个白名单:
CORS_ALLOWED_ORIGINS = ["https://www.php.cn/link/8e5687e2d6ab87e5da2f833f3e8986a4", "https://www.php.cn/link/92cdc3666b7883ebeed2973e70725bb1"](不能用*+CORS_ALLOW_CREDENTIALS = True)
示例片段:
INSTALLED_APPS = [
'corsheaders',
# ... 其他 app
]
<p>MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 必须靠前
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',</p><h1>注意:SessionMiddleware 必须在 CorsMiddleware 之后!</h1><pre class="brush:python;toolbar:false;">'django.middleware.common.CommonMiddleware',
# ...]
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
CORS_ALLOWED_ORIGINS = [ "https://www.php.cn/link/8e5687e2d6ab87e5da2f833f3e8986a4", "https://www.php.cn/link/92cdc3666b7883ebeed2973e70725bb1", ] CORS_ALLOW_CREDENTIALS = True # 如需带 cookies 登录
CORS_ALLOW_ALL_ORIGINS = True 能不能用?
开发阶段可以临时开,但上线必须关。它等价于返回 Access-Control-Allow-Origin: *,而一旦设了这个值,浏览器禁止同时发送凭证(withCredentials: true),会导致 sessionid 或 csrftoken 丢失。
真实项目中更安全的做法是:
- 开发环境用明确的
CORS_ALLOWED_ORIGINS列表 - 生产环境通过环境变量动态加载域名(如
os.getenv("CORS_ORIGINS", "").split(",")) - 如果前端部署在子路径(如
https://example.com/app/),注意 Origin 是整个协议+域名+端口,不包含路径
另外,CORS_ALLOW_HEADERS 默认已覆盖常见头(content-type, x-requested-with, authorization),除非你用了自定义 header(如 X-Trace-ID),否则不用动。
为什么 OPTIONS 请求返回 404 或 500?
Django 默认不自动响应跨域预检请求,django-cors-headers 会劫持 OPTIONS 并返回 200,但前提是中间件生效且没被其他逻辑拦截。
排查要点:
- 确认
CorsMiddleware没被注释或拼错(比如写成CorsMiddleWare) - 检查是否在某个视图或中间件里提前 return 了 Response,跳过了后续中间件
- 运行
python manage.py showmigrations看corsheaders是否被识别(它不提供 migration,但可验证是否加载) - 用 curl 测试:
curl -H "Origin: https://www.php.cn/link/8e5687e2d6ab87e5da2f833f3e8986a4" -I http://localhost:8000/api/login/,看响应头是否含Access-Control-Allow-Origin
最容易被忽略的一点:Django 的 DEBUG = False 时,如果 ALLOWED_HOSTS 没包含前端域名,连预检都进不到中间件,直接 400 Bad Request —— 这个错误和 CORS 无关,但现象类似。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










