Django AJAX POST请求403错误:CSRF验证失败解决方案与原理分析

何川
何川
发布时间:2026-10-13| 4人浏览过
原创

本文详解Django中使用AJAX发送POST请求时遇到的403 CSRF验证失败问题。通过分析官方JS解决方案与手动提取token两种方法,指出核心在于HTML中必须保留{% csrf_token %}以生成浏览器cookie。即使使用简化JS代码,若清除Cookie导致csrftoken丢失仍会报错,掌握token传递机制即可彻底解决该问题。

Django AJAX POST请求403错误:CSRF验证失败解决方案与原理分析

前言

问题背景与常见误区

在近期学习Django框架的过程中,尝试通过AJAX向后端发送POST请求时,直接收到了403错误提示,指出CSRF验证失败。此前在使用Django模板渲染页面时,只需在模板中添加{% csrf_token %}标签即可自动处理CSRF保护;然而,当采用AJAX方式发送POST请求时,这种传统的模板处理方式便不再直接生效。

文章末尾提供了更为简便的解决思路,前文所述方法相对繁琐。

官方JS解决方案与注意事项

经查阅网络资料及参考多位博主的经验,发现Django官方文档中其实已有明确的解决指引。其基本处理流程如下:

具体操作是新建一个JavaScript文件,将网络上提供的解决代码粘贴其中,然后在需要使用AJAX的页面中引入该JS文件。需要注意的是,如果所找的解决代码依赖于jQuery,则必须确保在引入jQuery库之后再引入该解决代码(因为网络上的解决方案众多,既有原生JS版本也有基于jQuery的版本,顺序至关重要)。

文末附上了本人使用的JS相关代码,读者也可自行搜索其他方案。

如果上述常规方法未能解决你的问题,那么你可能和我遇到了同一个隐蔽的陷阱。

深层原因:Cookie与Token的依赖关系

虽然应用上述方法后问题一度解决,但随着我对代码进行多次修改并清除了相关页面的Cookie,甚至在休息片刻后重新运行程序时,403 CSRF错误再次出现。百思不得其解之际,我重新查阅了Django官方文档的相关部分,经过大量英文阅读后大致定位了问题根源。

我发现自己在HTML页面中删除了原本添加的{% csrf_token %}标签,加之手动清除了浏览器中的相关Cookie,导致csrftoken被彻底清除。此时刷新页面,HTML源码中已找不到{% csrf_token %},浏览器中也不存在csrftoken的Cookie值。在这种情况下,即便引入了相关的JS代码,也无法发挥作用。

打个比方:

  • 吃饭需要工具,即筷子,但如果连饭都没有,拿着筷子又能吃什么呢?
  • 这里的“筷子”指的是用于解决CSRF问题的JS代码,而“饭”则是HTML中的{% csrf_token %}标签,更准确地说,是浏览器中生成的名为csrftoken的Cookie。
  • 只有两者同时存在,才能彻底解决CSRF验证问题。

总结要点如下:

  • 在使用AJAX发送POST请求时,HTML页面中必须包含{% csrf_token %}标签,通常放置在body标签内即可满足要求。
  • 随后引入相应的JS解决代码。
  • 补充说明:此方法与是否使用表单关系不大,因为我的HTML页面中并未使用表单,而是直接通过点击按钮触发AJAX请求。

相关JS代码示例

需要引入的相关JS代码


$(document).ajaxSend(function(event, xhr, settings) {
  function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
      var cookies = document.cookie.split(';');
      for (var i = 0; i < cookies.length; i++) {
        var cookie = jQuery.trim(cookies[i]);
        // Does this cookie string begin with the name we want?
        if (cookie.substring(0, name.length + 1) == (name + '=')) {
          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
          break;
        }
      }
    }
    return cookieValue;
  }
  function sameOrigin(url) {
    // url could be relative or scheme relative or absolute
    var host = document.location.host; // host + port
    var protocol = document.location.protocol;
    var sr_origin = '//' + host;
    var origin = protocol + sr_origin;
    // Allow absolute or scheme relative URLs to same origin
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
      (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
      // or any other URL that isn't scheme relative or absolute i.e relative.
      !(/^(\/\/|http:|https:).*/.test(url));
  }
  function safeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }
 
  if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
  }
});

更简洁的手动传递Token方法

简单方法

  • 首先,在你需要发起AJAX POST请求的页面任意位置添加{% csrf_token %}标签。
  • 接着在浏览器中查看页面源码,会发现一个隐藏输入标签:<input type="hidden" name="csrfmiddlewaretoken" value="jlYb5LCP21TxGapw7OuO0xbHmRnyFzlgDapiDl1M1Vp6dOjPM4BlHOgOVeuPYQ27">。
  • 在发起AJAX POST请求并构建JSON参数时,采用以下方式将其作为参数传递。前两个参数为自定义内容,请自行忽略;键值对中的键名应为隐藏输入标签的name属性值,值则为其value属性值。
  • csrf = $('input[name="csrfmiddlewaretoken"]').val();
  • params = {'sku_id': sku_id, 'count': count, 'csrfmiddlewaretoken': csrf};
  • 通过这种方式将csrf参数传递给后端,即可避免403错误。相比前文使用的大段JS代码,这种方法要简洁得多。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。