Django中AJAX请求触发CSRF验证失败403错误求助
解决Django AJAX请求CSRF验证失败(403错误)的问题
核心错误点及修复方案
1. AJAX请求URL不匹配
你的AJAX代码中直接写了url: /defaultpg/,存在两个问题:
- 你已经通过
let URLd = "{% url 'defaultpg' %}"生成了模板渲染后的正确URL,应该直接复用这个变量 - 你的
urls.py中路由是path('defaultpg', ...),没有尾部斜杠,硬写/defaultpg/会导致路由不匹配
修复代码:
$.ajax({ type: "POST", url: URLd, // 替换为模板生成的正确URL // 其他参数保持不变 });
2. AJAX期望JSON但视图返回HTML
你给AJAX设置了dataType: "json",但视图defaultpg返回的是HTML页面(render(request, 'Entry/login.html')),这会导致即使请求成功,AJAX也会进入error回调。
修复视图代码:
如果需要返回JSON响应,修改视图:
from django.http import JsonResponse @csrf_protect def defaultpg(request): print("-----------------------") if request.method == "POST": name = request.POST.get("name") email = request.POST.get('email') password = request.POST.get('password') print(name, email, password) # 返回JSON格式响应 return JsonResponse({'status': 'success', 'message': '提交成功'}) return render(request, 'Entry/login.html')
3. CSRF Token传递冗余(可选优化)
你同时在headers和data中传递了CSRF Token,二者选其一即可,推荐保留headers方式更符合规范,可删除data中的csrfmiddlewaretoken字段简化代码。
完整修复后的AJAX代码片段
someForm.addEventListener("submit", (e) => { e.preventDefault(); var csrfToken = $("input[name='csrfmiddlewaretoken']").val(); let nameValue = nameInput.value; let emailValue = emailInput.value; let passwordValue = passwordInput.value; let isNameValid = /^[a-zA-Z]+$/.test(nameValue); let isEmailValid = /^\S+@\S+\.\S+$/.test(emailValue); let isPasswordValid = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/.test(passwordValue); if (isNameValid && isEmailValid && isPasswordValid) { alert("验证通过,正在提交..."); $.ajax({ type: "POST", url: URLd, headers: { "X-CSRFToken": csrfToken }, data: { name: nameValue, email: emailValue, password: passwordValue, }, dataType: "json", success: function (data) { alert(data.message); // 可在此添加页面跳转逻辑,比如:window.location.href = '/login/'; }, error: function (xhr) { alert("提交失败:" + (xhr.responseJSON?.message || "未知错误")); }, }); } else { if (!isNameValid) { alert("请输入有效的姓名(仅字母)"); } else if (!isEmailValid) { alert("请输入有效的邮箱地址"); } else { alert("密码必须包含大小写字母、数字,长度不少于8位"); } } });
额外注意事项
- 你的
settings.py中CsrfViewMiddleware仅存在一次,符合Django要求 - 手动访问
/defaultpg是GET请求,不会触发CSRF验证,所以能正常访问;AJAX是POST请求,必须通过CSRF验证才能通过
内容的提问来源于stack exchange,提问作者Aryan Bagwe
相关产品推荐
相关产品推荐

