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中间件验证流程

1.请求到来时执行process_request方法

  从浏览器携带的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)
view函数

 

文件上传

<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'})
view函数

 

ajax通过django的csrf校验

1.确保csrftoken的cookie

  在模板里加{% 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);
    }
  }
});

 

posted @ 2019-04-15 20:38  Sandy-123  阅读(164)  评论(0编辑  收藏  举报