Django跨域实战:从预检失败到Cookie丢失的深度解决方案
1. 为什么你的Django应用总是跨域失败?
当你的前端应用尝试从http://localhost:3000调用部署在http://api.example.com的Django后端时,浏览器会像一个严格的安检员一样拦截这个请求。这不是Django的bug,而是现代浏览器遵循的安全策略——同源策略(Same-Origin Policy)。但别担心,CORS(跨域资源共享)就是为此而生的通行证系统。
典型错误场景分析:
- 预检请求(OPTIONS)返回403:就像安检时你的证件不全
- 明明设置了
ALLOW_CREDENTIALS但Cookie丢失:好比带了护照却忘了签证 - 正则匹配的白名单失效:类似填对了门牌号却写错了街道名
# 最简危险配置(仅用于理解问题)
CORS_ALLOW_ALL_ORIGINS = True # 相当于"谁都可以进"
CORS_ALLOW_CREDENTIALS = True # 但这样组合会导致浏览器拒绝
关键认知:CORS配置需要前后端协同工作。前端fetch需要
credentials: 'include',后端需要精确的origin白名单和正确的header配置。
2. 预检请求(OPTIONS)失败的终极解决方案
当你的前端发起一个带自定义Header的POST请求时,浏览器会先发送OPTIONS请求进行"预检"。这时Django必须正确响应,否则实际请求根本不会发出。
调试步骤:
- 打开Chrome开发者工具 → Network
- 筛选
OPTIONS请求 - 检查响应头是否包含:
Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: content-type, x-csrftoken
正确配置示例:
# settings.py
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"https://your-production-frontend.com"
]
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS', # 必须明确列出
'PATCH',
'POST',
'PUT',
]
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken', # 如果你使用Django的CSRF保护
'x

313

被折叠的 条评论
为什么被折叠?



