Django POST请求报CSRF verification failed令牌长度错误排查
Django 403 CSRF 校验失败修复方案
这个报错的根源是两个写法问题,改完就好:
- CSRF token长度不对的直接原因:你用
$("#csrf_token").val()获取token的写法完全错了。Django模板里的{% csrf_token %}标签默认渲染出来的是name属性为csrfmiddlewaretoken的隐藏输入框,你写的id选择器根本选不到正确的DOM元素,取到的值要么是空、要么是HTML片段,长度和合法token不匹配,自然会被Django的CSRF中间件拦截。
正确取token选下面任意一种写法就行,别自己随便给标签加id瞎选:- 直接把模板渲染出的token赋值给JS变量,出错概率最低:
const csrfToken = "{{ csrf_token }}"; - 选中默认渲染的隐藏输入框取值:
// jQuery 写法 const csrfToken = $('input[name="csrfmiddlewaretoken"]').val();
- 直接把模板渲染出的token赋值给JS变量,出错概率最低:
- 还有个你没注意到的隐藏bug:前后端传参的字段名完全对不上。前端POST请求里传的用户名字段是
name,后端视图里取的是request.POST['user'],就算CSRF校验过了,这里也会直接抛KeyError导致请求崩溃。把前端传参的字段名和后端对齐:post("{% url 'savep' %}", { user: user_name, // 原来写的是name,改成和后端取值对应的user pass: user_pass, csrfmiddlewaretoken: csrfToken // 传入前面正确获取到的token }); - 最后做个简单校验:打开浏览器F12开发者工具,切到网络面板找到这个POST请求,查看请求载荷,确认
csrfmiddlewaretoken的值是60多位的随机字符串,不是undefined、空值或者HTML标签片段,就说明token传对了。另外要确认你用的这个post方法是把所有参数转成隐藏表单项放到请求体里提交的,不是把参数拼到URL后面,不然也会出现传参失败的问题。
内容的提问来源于stack exchange,提问作者Abhay Kumar
相关产品推荐
相关产品推荐

