zoukankan      html  css  js  c++  java
  • 70 ajax crsf插件 formdata对象.文件上传, 注册, 登录

    主要内容:https://www.cnblogs.com/maple-shaw/articles/9524153.html

    csrf中间件: csrf跨站请求伪造

      a : crsf的两个静态方法:

        csrf_exempt : 给单个视图排除校验

        csrf_protect: 给单个视图必须校验

    from django.views.decorators.csrf import csrf_exempt, csrf_protect
    
    # 可以通过csrf校验, 不注销csrf插件的情况下
    # @csrf_exempt 
    # def login(request):
    #     return render(request, 'login.html')
    # 给csrf设置了一层安全保证, 不允许通过
    @csrf_protect
    def login(request):
        return render(request, 'login.html')
    

      b : csrf的请求流程:

        从process_request方法:  从请求的cookie中获取csrf_token  ——》csrf_token   ——》request.META['CSRF_COOKIE']

        从process_view方法:

          1: 如果视图函数加上了csrf_exempt的装饰器,则不做校验

          2 : 如果请求方式是'GET', 'HEAD', 'OPTIONS', 'TRACE' 也不做校验

          3 : 其他的方式做校验:

        request.META.get('CSRF_COOKIE') —— 》 csrf_token

        request_csrf_token = ''

        # 从request.POST中获取csrfmiddlewaretoken对应的值
            request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
           # 从请求头中获取X-csrftoken 的值
            request_csrf_token = request.META.get(settings.CSRF_HEADER_NAME, '')
          request_csrf_token 和 csrf_token 做对比 
          如果校验成功 正常走
          如果校验不成功 拒绝

    2 浏览器向服务器发请求的方式

      a : 地址栏上输入地址 回车, get请求

      b : form表单提交数据, 点击submit,  post请求

      c : a标签

      d : ajax

    3 JSON内容的复习:

      在JavaScript中: 关于json对象和字符串转换的两个方法:

        JSON.parse(): 用于将一个json字符串转为JavaScript对象

        JSON.stringify(): 用于将JavaScript的值转换为json字符串  

    4 ajax  : 一个与服务器进行交互的技术

      a : 简介: 异步的JavaScript和XML, 即使用JavaScript语言与服务器进行异步交互, 传输的数据为XML,(也不只是xml), 不是一种新的编程语言, 而是一种使用现有的标准的新方法.

      b : 优点

        1 : 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

        2 : 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求

        总结:

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

        AJAX请求无须刷新整个页面;

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

      c : 实例: 页面输入两个整数, 通过ajax传输到后端进行计算出结果,返回.

    url中的代码:

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.index),
        url(r'^calc/', views.calc),
        url(r'^calcs/', views.calcs),
    ]

    views中的代码:

    from django.shortcuts import render, HttpResponse
    
    def index(request):
        i1, i2, i3 = '', '', ''
        if request.method == 'POST':
            i1 = int(request.POST.get('i1'))
            i2 = int(request.POST.get('i2'))
            i3 = i1 + i2
        return render(request, 'index.html', {'i1':i1, 'i2': i2, 'i3': i3})
    
    import time
    def calc(request):
        print(request.POST)
        i1 = int(request.POST.get('i1'))
        i2 = int(request.POST.get('i2'))
        i3 = i1 + i2
        time.sleep(5)
        return HttpResponse(i3)
    
    def calcs(request):
        i1 = request.POST.get('i1')
        i2 = request.POST.get('i2')
        i3 = i1 + i2
        return HttpResponse(i3) 

    html中的代码

    <body>
    <input type="text" name="i1">+
    <input type="text" name="i2" >=
    <input type="text" name="i3">
    <button  id="b1">计算</button>
    <hr>
    <input type="text" name="ii1">+
    <input type="text" name="ii2" >=
    <input type="text" name="ii3">
    <button  id="b2">计算</button>
    
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        $('#b1').click(function () {
            $.ajax({
                url:'/calc/',
                type:'post',
                data:{
                    i1 : $('[name="i1"]').val(),
                    i2 : $('[name="i2"]').val(),
                },
                success:function (ret) {
                    console.log(ret);
                    $('[name="i3"]').val(ret)
                }
                })
        });
    
        $('#b2').click(function () {
        $.ajax({
            url:'/calcs/',
            type:'post',
            data:{
                i1 : $('[name="ii1"]').val(),
                i2 : $('[name="ii2"]').val(),
            },
            success:function (ret) {
                console.log(ret);
                $('[name="ii3"]').val(ret)
            }
            })
        });
    
    </script>
    </body>
    </html>
    

      d : ajax发post请求, 通过csrf验证的三种方法:

        1: 页面中使用{% csrf_token%} 

                  $('#b1').click(function () {
    				$.ajax({
    					url: '/csrf_test/',
    					type: 'post',
    					data: {
    						csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val(),  # **********
    						name: 'alex',
    						age: '73',
    					},
    					success: function (res) {
    						console.log(res);
    
    
    					}
    				})
    			});
    			
    

        2 : 通过获取返回的cookie中的字符串 放置在请求头中发送

    $('#b1').click(function () {
    				$.ajax({
    					url: '/csrf_test/',
    					type: 'post',
    					headers: {"X-CSRFToken": $('[name="csrfmiddlewaretoken"]').val()},
    					data: {
    						name: 'alex',
    						age: '73',
    
    					},
    					success: function (res) {
    						console.log(res);
    					}
    				})
    			});
    

         结论 : 由于每一次都这么写太麻烦了,可以使用$.ajaxSetup()方法为ajax请求统一设置。

       3 全局设置:

          注意: 使用$.ajaxSetup()方法为ajax请求统一设置. 此时需要建一个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');
    View Code
    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);
        }
      }
    });
    View Code

         从cookie中取值, 必须有cookie

            有cookie的两种方式

              1 使用{%csrf_token%};

              2   from django.views.decorators.csrf import ensure_csrf_cookie

                这个时候需要使用ensure_csrf_cookie()装饰器强制设置Cookie。

      $('#b2').click(function () {
            $.ajax({
                url: '/csrf_test/',
                type: 'post',
    
                data: {},
                success: function (res) {
                    console.log(res);
    
    
                }
            })
        });
    

        4 三种方法的views的代码:

    from django.views.decorators.csrf import ensure_csrf_cookie
    @ensure_csrf_cookie
    def csrf_test(request):
        if request.method == 'POST':
            print(request.POST)
            return HttpResponse('测试成功')
        return render(request, 'csrf_test.html')
    

    5 利用ajax实现文件上传

      FormData对象: 可以把所有表单元素的name与value组成一个queryString,提交到后台。 在使用ajax提交时,使用FormData对象可以减少拼接queryString的工作量 

        创建一个FormData空对象,然后使用append方法添加key/value:

    formData.append('f1', $('#f1')[0].files[0]);    # 由于jquery获取的对象是列表形式, 取出索引获取一个dom对象, .files获取文件列表, 取索引获取该文件
    

      文件上传操作的代码:

    <body>
    {% csrf_token %}
    <input type="file" id="f1">
    <button type="button" id="b1">上传</button>
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        $('#b1').click(function () {
            var formData = new FormData();
            formData.append('csrfmiddlewaretoken',$('[name="csrfmiddlewaretoken"]').val());
            {#FormData添加文件类型数据#}
            formData.append('f1', $('#f1')[0].files[0]);
            $.ajax({
                url:'/upload/',
                type:'post',
                data:formData,
                processData:false,
                contentType:false,
                success:function (ret) {
                    console.log(ret)
                }
            })
        })
    </script>
    

      views的内容:

    def upload(request):
        if request.method == 'POST':
            print(request.FILES)
            fileobj = request.FILES.get('f1')
            with open(fileobj.name, mode='wb') as f:   fileobj有name属性.
                # chunks一点一点的读
                for i in fileobj.chunks():
                    f.write(i)
            return HttpResponse('ok')
        return render(request, 'upload.html')
    

    注册: 涉及到的内容, jquery绑定事件, ajax中没有$(this)方法

    html中的内容:

    <body>
    <input type="text" id="t1" name="user"><span id="s1" style="color:red;"></span>
    {#<button id="b1">注册</button>#}
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        $('#t1').blur(function () {
            {#console.log($(this));#}
            _this = $(this);
            {#由于ajax中没有$(this)这个方法,所以设置了一个全局变量#}
            $.ajax({
                url:'/reg/',
                type:'post',
                data:{
                    user:$('#t1').val()
                },
                success:function (res) {
                    console.log(res);
                    {#$('#s1').text(res)#}
                    _this.next().text(res)
                }
    
            })
        }).focus(function () {
            _this.next().text('')
        })
    </script>
    

     views中的代码:

    def reg(request):
        if request.method == 'POST':
            print(request.POST)
            user = request.POST.get('user')
            # 从数据库中找到对象
            obj = models.User.objects.filter(user=user).first()
            if obj:
                return HttpResponse('该用户名已存在')
            else:
                return HttpResponse('该用户名可以使用')
        return render(request, 'reg.html')
    

    7 登录: 涉及到的内容  location.href = ''  

    html中的代码:

    <body>
    <input type="text" name="user" id="t1">
    <input type="password" name="pwd" id="p1">
    <button id="b1">登录</button>
    <script src="/static/jquery-3.3.1.min.js"></script>
    <script>
        $('#b1').click(function () {
            $.ajax({
                url:'/login/',
                type:'post',
                data: {
                    user: $('#t1').val(),
                    pwd: $('#p1').val()
                },
                success: function (res) {
                    console.log(res);
                    if(res.status == '0'){
                        location.href = res.url
                    }
                    else{
                        alert(res.msg)}}
            })
        })
    </script>
    </body>
    

     views中的代码:

    # 登录
    from django.http import JsonResponse
    def login(request):
        # 从ajax中的post方法中提交的数据中取出user和pwd
        if request.method == 'POST':
            ret = {'status': '0', 'msg': ''}
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
        #   数据库中找到对应的对象:
            obj = models.User.objects.filter(user=user, pwd=pwd)
            if obj:
                ret['url'] = '/upload/'
                return JsonResponse(ret)
        # 如果该对象存在, 返回登录成功
            else:
                ret['status'] = '1'
                ret['msg'] = '用户名或者是密码错误'
                return JsonResponse(ret)
        # 如果不存在, 返回用户名或者是密码错误.
        return render(request, 'login.html')
    

      

      

      

  • 相关阅读:
    软工1816 · 作业(十一)事后诸葛亮
    软工1816·Alpha冲刺(10/10)
    软工1816 · Alpha冲刺(9/10)
    软工1816 · Alpha冲刺(8/10)
    软工1816 · Alpha冲刺(7/10)
    软工1816 · Alpha冲刺(6/10)
    软工1816 · Alpha冲刺(5/10)
    软工1816 · 作业(九)团队现场编程实战
    团队项目评测
    Beta冲刺前准备
  • 原文地址:https://www.cnblogs.com/gyh412724/p/9800568.html
Copyright © 2011-2022 走看看