Ajax相关 及 解决csrf_token、Forbidden(CSRF)问题

一、

  AJAXAsynchronous Javascript And XML)翻译成中文就是异步的JavascriptXML”

  即使用Javascript语言与服务器进行异步交互,传输数据。传输的数据不只是XML。

       特点优势: 

    1. AJAX使用JavaScript技术向服务器发送异步请求

    2. AJAX请求无须刷新整个页面,即可与服务器交换数据并更新部分网页内容

    3. 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高 

     即(异步不等待)(局部刷新)(高性能)

  ajax的使用:

    $.ajax( {  } )   参数如下

   $.ajax({
         url: "/calc/",           // 请求地址
         type: "post",           // 请求的方式
         data: {"name": "kingon", }  // 发送的数据
         dataType: "JSON",            // 希望返回的数据格式,即按照什么规矩解释返回的数据。
         success: function (res) {   // 请求被成功响应之后会做的事儿
           console.log(res)
         },
         error: function (err) {
           console.log(err)       // 请求发生错误时会做的事儿
         }
     })

  发送的数据 data中不能发生嵌套,深层数据取不到。

  嵌套等复杂的数据要做处理(一般整个data做JSON格式化,而非下例)。

  data: {
   "name": "kingon",
  "hobby": JSON.stringify(["抽烟", "喝酒", "吹牛逼"]),
  }

   原生JS 发 ajax:

 1 var b2 = document.getElementById("b2");
 2   b2.onclick = function () {
 3     // 原生JS
 4     var xmlHttp = new XMLHttpRequest();
 5     xmlHttp.open("POST", "/ajax_test/", true);
 6     xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 7     xmlHttp.send("username=q1mi&password=123456");
 8     xmlHttp.onreadystatechange = function () {
 9       if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
10         alert(xmlHttp.responseText);
11       }
12     };
13   };
View Code

二、解决Forbidden(CSRF)方法

  首先、解决csrf_token关键点是request请求,必须要携带有token随机字符串。

    方法1: 在请求体Body中携带。在ajax请求的传送数据(data)中设置 csrfmiddlewaretoken 值。

    方法2: 在请求头Headers中携带。在ajax请求头(headers)中设置 X-CSRFToken 值。

         注意:ajax异步请求时,可以使用 $.ajaxSetup( ) 方法为ajax请求统一设置请求头。

  

  那么、关于如何获取token随机字符串值,有如下方法:

    方法1:渲染页面中加上  {% csrf_token %} 。(在Django中,因为 {% %} 是Django的模板语言)

        它会在页面渲染出一个隐藏的input标签,它有属性name="csrfmiddlewaretoken", 值就是token随机字符串。

           通过属性选择器 $("[name='csrfmiddlewaretoken']").val() 取到csrfmiddlewaretoken值。

       (所以表单中加{%csrf_token%},button按钮 submit 提交数据时,会将token随机字符串以键值对的形式一并提交。)

       (因为submit会搜集form内所有input标签的数据一并提交)

        

        结合上面“首先”中方法1,解决csrf_token如下:

      $.ajax({
       url: "/cokie_ajax/",        // 请求地址
      type: "POST",            // 请求的方式
       data: {
       "username": "kingon",
       "password": 123456,
       "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(),
       },
      dataType: "JSON", // 希望返回的数据格式,即按照什么规矩解释返回的数据。
       success: function (res) {   // 请求被成功响应之后会做的事儿
       console.log(res)
       },
      })

  

    方法2: 通过获取页面渲染时返回的Cookie中的csrftoken的value值,就是所需token随机字符串。 

        形式 2.1:    

        $.cookie('csrftoken')  ------>>> token随机字符串

          注意:需要引入一个jquery.cookie.js插件。

        $.ajax({
        url: "/cookie_ajax/",
        type: "POST",

        // 从Cookie取csrftoken,并设置到请求头中
        headers: {"X-CSRFToken": $.cookie('csrftoken')},

        data: {"username": "kingon", "password": 123456},
        success: function (data) {
        console.log(data);
        }
        })

        形式 2.2:

          不引插件,自己写一个getCookie 方法,从Cookie中取csrftoken值      

          自己组个插件,写个方法从cookie中取值
    
        变量 csrftoken ------>>> token随机字符串

          js静态文件中:

        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;
        }

        var csrftoken = getCookie('csrftoken');
   
   通过以上三种方法获取token随机字符串,然后将这个值设置在body中或者heaers中即可。

最终,总结解决csrf_token问题

    

    官方推荐方法(插件版):

     1、引入 jquery.cookie.js 插件    

      <script src="....../jquery.cookie.js"></script>

      在页面 js 中设置:

      function csrfSafeMethod(method) {

      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
      }

      $.ajaxSetup({
      beforeSend: function (xhr, settings) {
      if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
      }
      }
      });
      
    2、自己写个插件 ajax_csrftoken.js (插件中直接全局设置ajax请求头)(推荐!)
      页面中引入即可:
      <script src="....../ajax_csrftoken.js"></script>

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;
}

var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {

    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
    beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});
自定制插件csrf_token.js

  

 

 

  

ok

原文地址:https://www.cnblogs.com/kingon/p/9442741.html