一、
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。
即使用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 };
二、解决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); } } });
ok