You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django AJAX未附加CSRF Token至请求头却通过验证,原因何在?

问题:AJAX提交时未设置CSRF请求头仍通过验证?

我用Django 5.1.1做了个小项目,通过AJAX提交表单数据。表单里已经加了{% csrf_token %},原本打算把CSRF Token附加到XHR请求头中,但注释掉xhr.setRequestHeader('X-CSRFToken', csrfToken);这行代码后,CSRF验证居然还是成功通过,AJAX请求能正常发送并获取响应。只有移除{% csrf_token %}标签时,验证才会失败。按我的理解,没把CSRF Token放到请求头里应该验证失败,我忽略了什么点?

简化代码

HTML表单

<form id="form1" method="post" class="...">
 {% csrf_token %}

 <div>
  <label for="A" class=""></label>
  <input type="text" name="symbol" id="A" class="...">
 </div>

 <div>
   <button type="submit" id="submit-button"></button>
 </div>

</form>

JavaScript AJAX逻辑

document.getElementById('form1').addEventListener('submit', function(event) {
  event.preventDefault();

  const xhr = new XMLHttpRequest();
  const formData = new FormData(this);
  const csrfToken = this.querySelector('[name=csrfmiddlewaretoken]').value;

  xhr.open('POST', '/form-submit', true);
  // xhr.setRequestHeader('X-CSRFToken', csrfToken);
  xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
  xhr.send(formData);
});

Django视图函数

def index_view(request):
    return HttpResponse("", status=200)

Django中间件配置

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

解答

原因很直接:你用FormData(this)创建表单数据时,已经把{% csrf_token %}生成的隐藏input字段(name为csrfmiddlewaretoken)包含进去了。

Django的CsrfViewMiddleware会从两个渠道检查CSRF Token:

  • 请求头中的X-CSRFToken
  • POST请求体中的csrfmiddlewaretoken参数

只要其中一个渠道的Token验证通过,整个CSRF校验就会放行。所以哪怕你没设置请求头,FormData里携带的Token已经满足了验证要求。

只有当你移除{% csrf_token %}标签时,FormData里没有这个参数,同时请求头也没设置Token,才会触发CSRF验证失败。

内容的提问来源于stack exchange,提问作者solo dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:47:25