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

作者:yaominghui 时间:2021-06-11 19:47:32 

前言

今天学习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代码要简洁的多

标签:django,ajax,发送,post,请求,403,csrf,验证失败
0
投稿

猜你喜欢

  • pandas DataFrame运算的实现

    2021-06-02 21:08:22
  • 30万条数据,搜索文本字段的各种方式对比

    2010-05-02 10:17:00
  • python pillow库的基础使用教程

    2023-05-21 19:19:29
  • python采集博客中上传的QQ截图文件

    2021-03-03 16:45:25
  • 如何判断js脚本加载完成

    2008-11-04 13:53:00
  • Python学习之用pygal画世界地图实例

    2021-03-22 13:04:47
  • 简单仿LightBox效果

    2008-09-19 21:35:00
  • javascript开发经验谈

    2009-05-01 12:14:00
  • JavaScript文档生成工具

    2007-10-26 11:59:00
  • 用户研究角度看设计(1)“复制链接”的故事

    2008-12-26 17:48:00
  • 基于python实现百度翻译功能

    2023-09-06 15:14:18
  • python 字典操作提取key,value的方法

    2021-06-01 04:40:39
  • 详解Python的循环结构知识点

    2021-09-30 11:42:03
  • Python实现学生成绩管理系统

    2023-08-13 09:51:17
  • 如何把外网python虚拟环境迁移到内网

    2021-12-28 14:08:13
  • Atlas—微软的Ajax工具包

    2007-09-07 09:52:00
  • PHP PDOStatement::getColumnMeta讲解

    2023-06-22 08:34:14
  • jQuery点击改变链接的文本

    2010-03-19 18:11:00
  • django表单实现下拉框的示例讲解

    2022-03-24 09:18:25
  • 如何编写一个只在Web服务关闭时执行的程序?

    2009-11-08 19:03:00
  • asp之家 网络编程 m.aspxhome.com