为什么带@csrf_exempt装饰器的Django视图接收fetch POST请求仍报403 CSRF错误?
加了
@csrf_exempt仍报CSRF 403的核心原因 - 装饰器顺序错误导致
@csrf_exempt完全失效
Django的CSRF中间件只会检查最终暴露给路由的视图函数上是否带有csrf_exempt=True的标记。如果把@csrf_exempt放在其他装饰器(比如@login_required)的内层,外层装饰器会返回一个全新的包装函数,这个新函数不会继承csrf_exempt的标记,CSRF中间件仍然会对请求做校验,自然会触发403。同时需要确认@csrf_exempt是从django.views.decorators.csrf模块正确导入的,错误路径导入的装饰器不会给视图打上有效的免校验标记。 - 路由匹配错误导致请求没有打到免CSRF的视图上
报错信息显示403来自/profile/follow路径,需要检查URL配置中这个路径对应的视图,是否真的是你写的加了@csrf_exempt的follow视图,存在配置错位、指向其他需要CSRF校验的视图的可能。同时JS里用相对路径follow发请求时,会根据当前页面的URL动态拼接请求地址,很容易出现路径拼接错误,最终请求打到了其他视图上。
代码中影响功能正常运行的其他隐藏问题
- 请求格式与参数解析逻辑不匹配
JS请求设置了Content-Type: application/json,但Django的request.POST只会解析表单格式的请求体,对JSON格式的请求体而言request.POST是空的,用request.POST.get()根本拿不到传入的参数,就算通过CSRF校验,也会因为取不到用户信息抛出数据库查询错误。 - 参数键名不匹配
JS发送的参数字段是follower,但视图里取参数时写的是request.POST.get('follow'),字段名对不上,就算能正常解析请求体,也拿不到follower对应的用户数据。 - 模型数据修改未生效
代码里用append往用户模型的followers、following字段追加数据后,没有调用模型实例的save()方法,修改只会停留在内存里,不会真正写入数据库。 - JS逻辑错误
同步执行的console.log中引用了异步回调里才会返回的data变量,会直接抛出引用错误。
对应修复方案
- 调整装饰器顺序,保证
@csrf_exempt是最外层的装饰器,让最终暴露给路由的视图函数带有免CSRF的标记 - 把JS里的fetch请求路径改成明确的绝对路径,比如
fetch('/profile/follow'),避免相对路径拼接错误 - 统一请求格式与解析逻辑:要么把JS的
Content-Type改成表单格式,用URLSearchParams构造请求体,和request.POST的解析逻辑对应;要么保持JSON格式,在视图里用json.loads(request.body)解析请求体获取参数,同时把视图里取follower的键名改成和JS发送的一致。 - 追加完模型字段的修改后,调用
save()方法把变更写入数据库 - 把需要用到
data变量的console.log移到fetch的.then()回调内部,和其他依赖返回数据的逻辑放在一起
内容的提问来源于stack exchange,提问作者Bernardino Sassoli de' Bianchi
相关产品推荐
相关产品推荐

