在Django中使用csrftoken发起Ajax POST请求仍遇403错误的原因
解决Ajax POST请求403 CSRF错误的排查方案
先看你代码里的几个明显问题:
- 重复传递CSRF Token:你同时在
data参数里传了csrfmiddlewaretoken,又在headers里设置了X-CSRFToken。Django支持两种传递方式,但重复传递没必要,反而可能引发未知问题,建议二选一。 - 搜索值获取错误:
document.getElementById("search-articles").value是在拿表单元素的value属性,但表单本身没有这个属性。你需要获取表单内的输入框的值,比如如果输入框的name是q,应该改成$('#search-articles [name="q"]').val()或者document.querySelector('#search-articles [name="q"]').value。
修正后的代码示例
$('#search-articles').on('submit', function(event) { event.preventDefault(); const $form = $(this); // 切换显示状态 $("#loading").show(); $("#search-bar, #articles").hide(); function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); // 匹配cookie名称 if (cookie.startsWith(name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } $.ajax({ url: "{% url 'stocks_sites:get_news_articles' %}", type: "POST", data: { "q": $form.find('[name="q"]').val() // 正确获取输入框的值 }, headers: { "X-CSRFToken": getCookie("csrftoken") }, success: function(response) { $("#loading").hide(); $("#search-bar, #articles").show(); $("#search-bar").html(response[0]); $("#articles").html(response[1]); }, // 新增错误回调,方便调试 error: function(xhr) { console.log("请求错误:", xhr.responseText); $("#loading").hide(); $("#search-bar, #articles").show(); } }); });
其他需要排查的点:
- CSRF Cookie读取权限:检查Django配置里的
CSRF_COOKIE_HTTPONLY,如果设为True,前端JS无法读取这个cookie,此时必须改用csrfmiddlewaretoken放在data里传递,同时去掉headers里的X-CSRFToken设置。 - 模板URL渲染正确性:查看页面源码,确认
{% url 'stocks_sites:get_news_articles' %}被渲染成了实际的后端接口URL,而不是原样输出模板标签。如果没渲染,说明这段JS没有放在Django模板里执行,或者模板语法有误。 - 后端视图配置:确保视图没有使用
@csrf_exempt装饰器(如果需要CSRF验证的话),并且视图正确处理POST请求。 - 查看请求详情:打开浏览器开发者工具的Network面板,查看发送的POST请求:
- 检查Request Headers里是否有
X-CSRFToken,或者Form Data里是否有csrfmiddlewaretoken; - 查看Response的具体内容,Django的403页面通常会给出明确的错误原因,比如"CSRF token missing or incorrect"。
- 检查Request Headers里是否有
内容的提问来源于stack exchange,提问作者JayTicku
相关产品推荐
相关产品推荐

