Laravel前端Ajax请求Django DRF后端CORS头不允许错误如何解决
问题原因与解决办法
核心原因
- 前端AJAX配置错误:所有
Access-Control-*开头的字段都是服务端返回的CORS响应头,用于浏览器校验跨域请求合法性,不需要前端在请求头中主动携带。你在请求头中添加了这些字段后,相当于新增了自定义请求头,而Django corsheaders默认未允许这类头通过,因此预检OPTIONS请求直接被拦截,无法进入后续POST流程。 - Django CORS配置冲突:你同时开启了
CORS_ORIGIN_ALLOW_ALL=True(允许所有源跨域)和CORS_ALLOW_CREDENTIALS = True(允许跨域携带凭据),这两个配置是互斥的,corsheaders不支持该组合,会导致配置失效。
解决步骤
第一步:修改前端AJAX配置
删除请求头中所有Access-Control-*开头的字段,仅保留业务需要的请求头即可,修改后的headers配置如下:
$.ajax({ headers: { // 若Django未开启CSRF校验,X-CSRF-TOKEN也可删除 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'), 'Authorization': 'Token ' + token, }, // 其余原有配置保持不变 })
第二步:修正Django CORS配置
- 首先确认
corsheaders中间件顺序,必须放在所有中间件的首位:
MIDDLEWARE = [ "corsheaders.middleware.CorsMiddleware", # 必须放在第一个位置 "django.middleware.common.CommonMiddleware", # 其余原有中间件保持顺序不变 ]
- 修正跨域配置,替换允许所有源的配置为指定前端源地址:
# 注释或删除这行配置 CORS_ORIGIN_ALLOW_ALL = True # 替换为你的Laravel前端实际访问地址,例如前端跑在8000端口就填对应的地址 CORS_ALLOWED_ORIGINS = [ "http://127.0.0.1:8000", ] CORS_ALLOW_CREDENTIALS = True # 显式声明允许的请求头,覆盖默认配置确保业务头正常通过 CORS_ALLOW_HEADERS = [ "accept", "accept-encoding", "authorization", "content-type", "origin", "x-csrftoken", "x-requested-with", ]
第三步:重启服务测试
重启Django服务后,清除浏览器缓存重新提交表单,预检OPTIONS请求即可正常通过,后续POST请求会正常触发。
内容的提问来源于stack exchange,提问作者afk
相关产品推荐
相关产品推荐

