Django中ajax发送post请求 报403错误CSRF验证失败解决方案


Posted in Python onAugust 13, 2019

前言

今天学习Django框架,用ajax向后台发送post请求,直接报了403错误,说CSRF验证失败;先前用模板的话都是在里面加一个 {% csrf_token %} 就直接搞定了CSRF的问题了;很显然,用ajax发送post请求这样就白搭了;

文末已经更新更简单的方法,上面的略显麻烦

上网上查了一下,看了几个别人的博客,才知道官网也早有说明解决办法,大致流程就是:

就是新建一个JavaScript文件,然后把网上给的代码粘贴进去,然后在你使用ajax的页面把它引入一下;当然,如果你在网上找到的解决代码包含JQuery的话,那就需要在引入的JQuery之后引入了(毕竟解决代码不唯一,网上一找一堆,基本都是对的,原生JS和带JQuery的都有);

文末会附上我使用的JS相关代码,也可以去网上找!

如果上述没有解决你的问题,那就说明你和我踩了同样的一个小坑........

用了上面查到的方法,直接就解决了我的问题,但是随着我对代码修修改改、清除了相关页面的cookie,吃个饭再运行,竟然又报403的CSRF错误了;百思不得其解的我又去Django官网看了一下相关部分的文档,一堆英文看看大概找到了问题;

我发现我把html页面里面原先加的 {% csrf_token %} 这个东西给删掉了,加上谷歌的相关页面cookie被我一清除,csrftoken就被咔嚓了,再刷新页面,去html页面里也找不到 {% csrf_token %} ,没有了csrftoken那个cookie值,即使有相关的JS代码也毛用没有了;

打个比方:

  • 你吃饭需要工具,也就是筷子,但是饭都没有,你拿个筷子吃什么呀!!!
  • 这里的筷子就是解决问题的JS代码,而饭就是这个 {% csrf_token %} ,更确切说因该是浏览器中的叫 csrftoken 的 cookie;
  • 两者都有了,才能彻底解决吃饭的问题;

总结下来:

  • 使用ajax发送post请求时,html页面里一定要有 {% csrf_token %},在body里应该就没什么大问题;
  • 然后引入相关的JS解决代码;
  • 补充一下,和表单没什么太大关系,因为我的html页面里就没有表单,直接通过点击按钮发送的ajax请求;

Django中ajax发送post请求 报403错误CSRF验证失败解决方案

需要引入的相关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'));
  }
});

简单方法

  • 首先在你需要发起ajax post请求的页面的里面随便一个地方加上 {% crsr_token %}
  • 然后浏览器里查看源码,会有这么一个隐藏标签:<input type="hidden" name="csrfmiddlewaretoken" value="jlYb5LCP21TxGapw7OuO0xbHmRnyFzlgDapiDl1M1Vp6dOjPM4BlHOgOVeuPYQ27">
  • 在发起ajax post 请求时,组织json参数时,以下面这种方式使其成为参数,前两个参数是我自定义的请自行忽略,其中键值对中的键名为input标签的name名,值就为其value值
  • csrf = $('input[name="csrfmiddlewaretoken"]').val();
  • params = {'sku_id': sku_id, 'count': count, 'csrfmiddlewaretoken': csrf};
  • 这样就可以把csrf中的参数传递给后端,就不会有403错误了,相比前面用了好大一段JS代码要简洁的多

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

Python 相关文章推荐
Python实现遍历windows所有窗口并输出窗口标题的方法
Mar 13 Python
在Django的视图中使用数据库查询的方法
Jul 16 Python
Python的Django框架中设置日期和字段可选的方法
Jul 17 Python
Python判断文件或文件夹是否存在的三种方法
Jul 27 Python
Python爬虫实现全国失信被执行人名单查询功能示例
May 03 Python
不知道这5种下划线的含义,你就不算真的会Python!
Oct 09 Python
解决Python下imread,imwrite不支持中文的问题
Dec 05 Python
python Django编写接口并用Jmeter测试的方法
Jul 31 Python
Python socket实现的文件下载器功能示例
Nov 15 Python
pytorch 实现cross entropy损失函数计算方式
Jan 02 Python
Python 实现将numpy中的nan和inf,nan替换成对应的均值
Jun 08 Python
Keras 实现加载预训练模型并冻结网络的层
Jun 15 Python
Python人工智能之路 jieba gensim 最好别分家之最简单的相似度实现
Aug 13 #Python
Python人工智能之路 之PyAudio 实现录音 自动化交互实现问答
Aug 13 #Python
Django rstful登陆认证并检查session是否过期代码实例
Aug 13 #Python
Python Request爬取seo.chinaz.com百度权重网站的查询结果过程解析
Aug 13 #Python
python实现对服务器脚本敏感信息的加密解密功能
Aug 13 #Python
python多线程+代理池爬取天天基金网、股票数据过程解析
Aug 13 #Python
Python字符串处理的8招秘籍(小结)
Aug 13 #Python
You might like
php中通过Ajax如何实现异步文件上传的代码实例
2011/05/07 PHP
解析关于wamp启动是80端口被占用的问题
2013/06/21 PHP
PHP实现的比较完善的购物车类
2014/12/02 PHP
php实现在限定区域里自动调整字体大小的类实例
2015/04/02 PHP
php 策略模式原理与应用深入理解
2019/09/25 PHP
laravel model 两表联查示例
2019/10/24 PHP
sina的lightbox效果。
2007/01/09 Javascript
解析arp病毒背后利用的Javascript技术附解密方法
2007/08/06 Javascript
JS时间选择器 兼容IE6,7,8,9
2012/06/26 Javascript
jquery ajax提交整个表单元素的快捷办法
2013/03/27 Javascript
javascript中基本类型和引用类型的区别分析
2015/05/12 Javascript
jQuery动态添加
2016/04/07 Javascript
Angular-Ui-Router+ocLazyLoad动态加载脚本示例
2017/03/02 Javascript
vue.js事件处理器是什么
2017/03/20 Javascript
koa router 多文件引入的方法示例
2019/05/22 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
2019/08/27 Javascript
VSCode Vue开发推荐插件和VSCode快捷键(小结)
2020/08/08 Javascript
原生微信小程序开发中 redux 的使用详解
2021/02/18 Javascript
[07:20]2014DOTA2西雅图国际邀请赛 选手讲解积分赛第二天
2014/07/11 DOTA
[03:45]Newbee战队出征西雅图 决战2016国际邀请赛
2016/08/02 DOTA
[02:32]【DOTA2亚洲邀请赛】iceice,梦开始的地方
2017/03/13 DOTA
[41:52]DOTA2-DPC中国联赛 正赛 CDEC vs Dynasty BO3 第二场 2月22日
2021/03/11 DOTA
python3使用requests模块爬取页面内容的实战演练
2017/09/25 Python
python学习之hook钩子的原理和使用
2018/10/25 Python
解决PySide+Python子线程更新UI线程的问题
2019/01/11 Python
Python中判断子串存在的性能比较及分析总结
2019/06/23 Python
Pytorch 实现自定义参数层的例子
2019/08/17 Python
Python pandas RFM模型应用实例详解
2019/11/20 Python
Python 实现将大图切片成小图,将小图组合成大图的例子
2020/03/14 Python
详细分析Python可变对象和不可变对象
2020/07/09 Python
Python如何急速下载第三方库详解
2020/11/02 Python
详解Python中如何将数据存储为json格式的文件
2020/11/18 Python
澳大利亚家居用品零售商:Harris Scarfe
2020/10/10 全球购物
计算机求职信
2013/12/01 职场文书
给面试官的感谢信
2014/02/01 职场文书
颂军魂爱军营演讲稿
2014/09/13 职场文书