Django之CSRF和AJAX
JSON
什么是 JSON ?
- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON 独立于语言 *
- JSON 具有自我描述性,更易理解
* JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。
stringify与parse方法
JavaScript中关于JSON对象和字符串转换的两个方法:
- JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象
JSON.parse('{"name":"alex"}');
JSON.parse('{name:"alex"}') ; // 错误,属性名必须使用双引号
JSON.parse('[18,undefined]') ; // 错误,不能使用undefined
- JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。
JSON.stringify({"name":"alex"})
CSRF
django为用户实现防止跨站请求伪造的功能,通过中间django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。
全局:
中间件 django.middleware.csrf.CsrfViewMiddleware
局部:
-
csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
-
csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
开启csrf后 , 当用post提交数据的时候,django会去检查是否有一个csrf的随机字符串,如果没有就会报错.
通过form提交
在form表单里面需要添加{%csrf_token%}
这样当你查看页面源码的时候,可以看到form中有一个input是隐藏的
当用户访问login页面的时候,会生成一个csrf的随机字符串,,并且cookie中也存放了这个随机字符串,当用户再次提交数据的时候会带着这个随机字符串提交,如果没有这个随机字符串则无法提交成功
cookie中存放的csrftoken如下图
csrf装饰器
from django.views.decorators.csrf import csrf_exempt,csrf_protect,ensure_csrf_cookie
csrf_exempt #某个视图不需要进行csrf校验上
csrf_protect #某个视图需要进行csrf校验
ensure_csrf_cookie #确保生成csrf的cookie
csrf_exempt
csrf_exempt,不能加在类上,也不能加在方法上,只能加在dispatch上
作用:中间件开启csrf校验,针对POST等可通过这个装饰器豁免,不在进行校验
方法一:
class Login(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
ret = super().dispatch(request, *args, **kwargs)
return ret
方法二:
@method_decorator(csrf_exempt,name='dispatch')
class Login(View):
def get(self, request, *args, **kwargs):
pass
def post(self, request, *args, **kwargs):
pass
csrf_protect
当中间件django.middleware.csrf.CsrfViewMiddleware禁用后,可通过csrf_protect开启,可以加在方法上
ensure_csrf_cookie
生成csrftoken的cookie
@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs):
return render(request, 'login.html')
csrf功能
1.csrf中间件中执行process_request:
1. 从cookie中获取到csrftoken的值
2. csrftoken的值放入到 request.META
2.执行process_view
-
查询视图函数是否使用csrf_exempt装饰器,使用了就不进行csrf的校验
-
判断请求方式:
-
如果是GET', 'HEAD', 'OPTIONS', 'TRACE'
不进行csrf校验
- 其他的请求方式(post,put)
进行csrf校验:
1.获取cookie中csrftoken的值
获取csrfmiddlewaretoken的值
能获取到 ——》 request_csrf_token
获取不到 ——》 获取请求头中X-csrftoken的值 ——》request_csrf_token
比较上述request_csrf_token和cookie中csrftoken的值,比较成功接收请求,比较不成功拒绝请求。
-
ajax
1.发请求的方式
1.地址栏输入地址 GET
2.form表单 GET/POST
3.a标签 GET
2.ajax 和 json
-
json 是各系统,各编程语言间传输数据的一种规定格式
-
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
- 优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
- AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。是一个异步的过程
-
javascript 对 json对象的方法
JSON.parse(),# 将用于将一个 JSON 字符串转换为 JavaScript 对象 JSON.parse('{"name":"alex"}'); JSON.stringify(),用于将 JavaScript 值转换为 JSON 字符串。 JSON.stringify({"name":"alex"}) -
AJAX 就是使用js的技术发送请求和接受响应的
特点:
1.异步的 ,AJAX使用JavaScript技术向服务器发送异步请求;
2.是局部刷新的,AJAX请求无须刷新整个页面
3.传输的数据量少,因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;
3. AJAX常用应用场景
-
搜索引擎根据用户输入的关键字,自动提示检索关键字。
-
注册时候的用户名的查重。
-
这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。
-
整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
-
当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
-
当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为lemontree7777777的用户是否存在
-
4. jquery 实现ajax请求
注意 : 对于发送给服务器的data数据中,若值不是字符串形式,需要将其转换成字符串类型。
data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])}
先导入jquery.js
$.ajax({
url: '/calc/',
type: 'post',
data: {
a: $("[name='i1']").val(),
b: $("[name='i2']").val(),
},
success: function (res) { --->成功接收请求,res就是就收到的项响应体
$("[name='i3']").val(res)
},
error:function (error) { -->接受失败了的错误信息
console.log(error)
}
})
<--ajax上传文件的实现-->
<input type="file" id="f1">
<button id="b1">上传</button>
$('#b1').click(function () {
var formobj = new FormData();
formobj.append('file',document.getElementById('f1').files[0]);
// formobj.append('file',$('#f1')[0].files[0]); //添加键值对,值为该文件对象
formobj.append('name','alex');
$.ajax({
url: '/upload/',
type: 'post',
data:formobj ,
processData:false, // 告诉jQuery不要去处理发送的数据
contentType:false, // 告诉jQuery不要去设置Content-Type请求头
success: function (data) {
console.log(data)
},
})
})
//py文件
def upload(request):
print(request.FILES) -->file
print(request.POST) -->name
return render(request,'upload.html')
5.ajax 通过crsf 的校验
-
前提条件 :确保有csrftoken的cookie
在页面中使用{% crsf_token%}
加装饰器ensure_crsf_cookie
from django.views.decorators.csrf import csrf_exempt,csrf_protect, ensure_csrf_cookie -
给data中添加csrfmiddlewaretoken的值,在ajax请求中
data: { 'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val(), a: $("[name='i1']").val(), b: $("[name='i2']").val(), }, -
或者 --> : 加请求头
headers:{ 'x-csrftoken':$('[name="csrfmiddlewaretoken"]').val(), }, -
或者 --> : 使用文件
//ajax_setup.js文件 //自己写一个getCOOKIE方法 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'); //每一次都这么写太麻烦了,可以使用$.ajaxSetup()方法为ajax请求统一设置。 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); } } });**注意: ** 使用从cookie中取csrftoken的方式,需要确保cookie存在csrftoken值。
如果你的视图渲染的HTML文件中没有包含 {% csrf_token %},Django可能不会设置CSRFtoken的cookie。这个时候需要使用ensure_csrf_cookie()装饰器强制设置Cookie。
django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie def login(request): pass

浙公网安备 33010602011771号