AJAX
csrf相关的装饰器
from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt, csrf_protect from django.views.decorators.csrf import ensure_csrf_cookie # 确保有cookie csrf_exempt # 当前的视图不需要CSRF校验 csrf_protect # 当前的视图需要CSRF校验 @method_decorator(csrf_exempt, name='dispatch') # CBV中 csrf_exempt装饰器只能加载dispatch上,单独加在函数上不起作用 class Form(View): def get(self, request): return render(request, 'form.html') def post(self, request): return render(request, 'form.html')
csrf中间件验证流程
从浏览器携带的cookie中获取csrftoken的值 赋值给request.META['CSRF_COOKIE']
2.执行process_view方法
1.查看视图是否加了csrf_exempt装饰器,
有,不需要csrf验证,返回None,正常流程向下执行;
没有,需要csrf校验
2.判断请求方式
'GET', 'HEAD', 'OPTIONS', 'TRACE' ,不需要csrf检验,返回None,继续执行
其他方式,需要csrf校验
3.进行csrf校验
request.META['CSRF_COOKIE'] 获取csrftoken的值
尝试从表单中获取csrfmiddlewaretoken的值(如果表单中设置了{% csrf_token %},生成隐藏的input标签,name属性为csrfmiddlewaretoken) ,能获取到的话 将csrfmiddlewaretoken的值和cookie中的csrftoken值做对比,一致则通过校验
在表单中获取不到 尝试从请求头中获取x-srftoken的值 获取到的话 再将csrfmiddlewaretoken的值和cookie中的csrftoken值做对比,一致则通过校验,否则拒绝请求
AJAX
json
在python中:
数据类型: 数字,字符串,列表,字典,布尔值,None
转化:json.dumps(python数据) json.dump(python数据,文件句柄f) 序列化
json.loads(json字符串) json.load(文件句柄f) 反序列化
在js中:
数据类型: 数字,字符串,列表,对象,布尔值,null
转化: json.stringify(js数据) 序列化
json.parse(json字符串) 反序列化
发请求的途径:
1.在地址栏中输入网址 get请求
2.a标签 get请求
3.form表单 get/post请求
method默认get请求,可以指定method="post"
action指定提交地址,不写默认移交到当前地址
input框要有那么属性 有时还要设置value值
提交可以使用button按钮 或者input标签 type="submit"
ajax是一个js技术,发送请求的一种途径,使用javascript语言与服务器进行异步交互,传输的数据是XML,json
ajax最大的优点是在不重新加载页面的情况下,可以与服务器交换数据并更新部分网页内容(给用户的感受是在不知不觉中完成请求和响应过程)
特点:
异步
局部刷新
传输的数据量小
计算机示例
<body> <div> <input type="text" name="i1">+ <input type="text" name="i2">= <input type="text" name="i3"> <button id="b1">计算</button> </div> <script src="/static/jquery.js"></script> <script> $('#b1').click(function () { $.ajax({ url: '/calc/', // 请求地址 type: 'post', // 请求方式 //headers: { // 'x-csrftoken': $('[name="csrfmiddlewaretoken"]').val() , //}, data: { // 请求数据 // csrfmiddlewaretoken:$('[name="csrfmiddlewaretoken"]').val(), i1: $('[name="i1"]').val(), i2: $('[name="i2"]').val(), }, success: function (res) { // 成功后执行 $('[name="i3"]').val(res) // location.href = 地址 // 重定向 }, error: function (res) { // 失败后执行 console.log(res) } }) });
### views函数 def index(request): if request.method == 'POST': i1 = request.POST.get('i1') i2 = request.POST.get('i2') i3 = int(i1) + int(i2) return render(request,'index.html',{'i1':i1,'i2':i2,'i3':i3}) return render(request,'index.html') def calc(request): i1 = request.POST.get('i1') i2 = request.POST.get('i2') i3 = int(i1) + int(i2) return HttpResponse(i3)
文件上传
<body> <div> <input type="file" id="f1"> <button id="b2">上传</button> </div> </body> <script src="/static/jquery.js"></script> <script> $('#b2').click(function () { var form_obj = new FormData(); // 创建文件对象 form_obj.append('f1', $('#f1')[0].files[0]); $.ajax({ url: '/upload/', type: 'post', data: form_obj, processData: false, //告诉jquery不用处理数据 contentType: false, // 告诉jquery不用处理contentType的请求头 message:JSON.stringify(['11','22','33']), //使用jquery中的json,将列表转化成字符串传递 success: function (res) { console.log(res) } }) }) </script>
from django.http.response import JsonResponse #导入序列化将字典或者列表转化为json字符串传递 def upload(request): f1 = request.FILES.get('f1') with open(f1.name,'wb') as f: for chunk in f1.chunks(): f.write(chunk) return JsonResponse({'status':0,'data':'ok'})
ajax通过django的csrf校验
在模板里加{% csrf_token %}
给视图函数加装饰器
from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie 函数
2.提供参数
1.提交的数据中加csrfmiddletoken的值
data: { 'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val(), i1: $('[name="i1"]').val(), i2: $('[name="i2"]').val(), },
2.加x-csrftoken的请求头
headers: { 'x-csrftoken': $('[name="csrfmiddlewaretoken"]').val() , },
3.文件导入
在静态文件中保存下面的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'); 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); } } });