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使用ftplib实现简易FTP客户端的方法
Jun 03 Python
玩转python爬虫之正则表达式
Feb 17 Python
Python实现复杂对象转JSON的方法示例
Jun 22 Python
Python数据结构与算法之二叉树结构定义与遍历方法详解
Dec 12 Python
python PrettyTable模块的安装与简单应用
Jan 11 Python
解决Pycharm界面的子窗口不见了的问题
Jan 17 Python
Python中请不要再用re.compile了
Jun 30 Python
Python将主机名转换为IP地址的方法
Aug 14 Python
DJango的创建和使用详解(默认数据库sqlite3)
Nov 18 Python
python之pymysql模块简单应用示例代码
Dec 16 Python
pandas DataFrame 数据选取,修改,切片的实现
Apr 24 Python
利用For循环遍历Python字典的三种方法实例
Mar 25 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_Flame(Version:Progress)的原代码
2006/10/09 PHP
浅析php过滤html字符串,防止SQL注入的方法
2013/07/02 PHP
PHP生成指定长度随机数最简洁的方法
2014/07/14 PHP
php多次include后导致全局变量global失效的解决方法
2015/02/28 PHP
php微信开发之关注事件
2018/06/14 PHP
Jquery 插件学习实例1 插件制作说明与tableUI优化
2010/04/02 Javascript
按钮JS复制文本框和表格的代码
2011/04/01 Javascript
formStorage 基于jquery的一个插件(存储表单中元素的状态到本地)
2012/01/20 Javascript
JavaScript DOM 编程艺术(第2版)读书笔记(JavaScript的最佳实践)
2013/10/01 Javascript
jQuery获取动态生成的元素示例
2014/06/15 Javascript
js 模式窗口(模式对话框和非模式对话框)的使用介绍
2014/07/17 Javascript
JavaScript中的alert()函数使用技巧详解
2014/12/29 Javascript
javascript感应鼠标图片透明度显示的方法
2015/02/24 Javascript
你不知道的高性能JAVASCRIPT
2016/01/18 Javascript
JavaScript中的Number数字类型学习笔记
2016/05/26 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
2016/10/12 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
2016/10/26 Javascript
微信小程序 wxapp画布 canvas详细介绍
2016/10/31 Javascript
TypeScript学习之强制类型的转换
2016/12/27 Javascript
html+javascript+bootstrap实现层级多选框全层全选和多选功能
2017/03/09 Javascript
Vue.Js中的$watch()方法总结
2017/03/23 Javascript
微信小程序商品详情页规格属性选择示例代码
2017/10/30 Javascript
nodejs操作mongodb的增删改查功能实例
2017/11/09 NodeJs
基于vue展开收起动画的示例代码
2018/07/05 Javascript
Vue 实现复制功能,不需要任何结构内容直接复制方式
2019/11/09 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
2021/01/07 Javascript
Python文件读取的3种方法及路径转义
2015/06/21 Python
详解Python3迁移接口变化采坑记
2019/10/11 Python
Python实现分数序列求和
2020/02/25 Python
如何基于python对接钉钉并获取access_token
2020/04/21 Python
售后服务承诺书范文
2014/03/26 职场文书
学校社团活动总结
2015/05/07 职场文书
风雨哈佛路观后感
2015/06/03 职场文书
Vue详细的入门笔记
2021/05/10 Vue.js
ant design charts 获取后端接口数据展示
2022/05/25 Javascript
MySQL数据库安装方法与图形化管理工具介绍
2022/05/30 MySQL