Python学习 Day 068

主要内容:

  • 1.ajax概述
  • 2.ajax相关
  • 3.上传文件

1.AJAX的概述

  • AJAXAsynchronous Javascript And XML)翻译成中文就是异步的JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
  • AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
  • AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
  • AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
    #同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    #异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

(1)示例:页面输入两个整数,通过AJAX传输到后端计算出结果并返回。

  • HTML 代码
    <body>
    {% csrf_token %}
    <p>
        <input type="text" name="i1">
        <input type="text" name="i2">
        <input type="text" name="i3">
        <button id="b1">计算</button>
    </p>
    <p>
        <input type="text" name="i4">
        <input type="text" name="i5">
        <input type="text" name="i6">
        <button id="b2">计算</button>
        <button id="b3">参数的测试</button>
    </p>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script>
        $('#b1').click(function(){
            $.ajax({
                url:'/calc/',
                type:'post',
                data :{
                    'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val(),
                    i1:$('[name="i1"]').val(),
                    i2:$('[name="i2"]').val()
                },
                success:function(res){
                    $('[name="i3"]').val(res)
                }
            })
        });
        $('#b2').click(function(){
            $.ajax({
                url:'/calc2/',
                type:'post',
                headers:{
                     'X-csrftoken': $('[name="csrfmiddlewaretoken"]').val(),
                },
                data :{
                    i1:$('[name="i4"]').val(),
                    i2:$('[name="i5"]').val()
                },
                success:function(res){
                    $('[name="i6"]').val(res)
                }
            })
        });
  • views.py 代码
    from django.shortcuts import render,HttpResponse
    # from django.views.decorators.csrf import ensure_csrf_cookie
    # @ensure_csrf_cookie
    def index(request):
        return render(request,'index.html')
    
    def calc(request):
        i1 = request.POST.get('i1','')
        i2 = request.POST.get('i2','')
        i3 = int(i1)+int(i2) if i1 and i2 else ''
        return HttpResponse(i3)
    
    def calc2(request):
        i4 = request.POST.get('i1', '')
        i5 = request.POST.get('i2', '')
        i6 = int(i4) + int(i5) if i4 and i5 else ''
        return HttpResponse(i6)
  • urls.py 代码
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.index),
        url(r'^calc/', views.calc),
        url(r'^calc2/', views.calc2),

(2)ajax优点

  • AJAX使用JavaScript技术向服务器发送异步请求;
  • AJAX请求无须刷新整个页面;
  • 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;

2.ajax相关

2.1 发请求的途径

  • a标签
  • form表单 GET/POST
  • 地址栏输入地址回车  GET

2.2参数

注: data参数中的键值对,如果值值不为字符串,需要将其转换成字符串类型

    $('#b3').click(function(){
        $.ajax({
            url:'/ajax_test/',
            type:'post',
            data:{
                name:'倚天屠龙记',
                time:'2003',
                place:'内地',
                actor: JSON.stringify(['苏有朋','高圆圆','张国立','贾静雯'])
            },
            success:function(res){
                alert(res)
            }
        })
    })

js实现AJAX

var b2 = document.getElementById("b2");
  b2.onclick = function () {
    // 原生JS
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open("POST", "/ajax_test/", true);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlHttp.send("username=q1mi&password=123456");
    xmlHttp.onreadystatechange = function () {
      if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
        alert(xmlHttp.responseText);
      }
    };
  }; 
js实现ajax

2.3  ajax可以提交POST 请求的方式(如何设置csrf_token)

(1) 在HTML页面中使用 {% csrf_token %},给POST提交数据中添加 csrfmiddlewaretoken的键值对

 data :{
      'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val(),
       i1:$('[name="i1"]').val(),
       i2:$('[name="i2"]').val()
},

(2)在HTML页面中使用 {% csrf_token %},在ajax中添加X-csrftoken的请求头

headers:{
  'X-csrftoken': $('[name="csrfmiddlewaretoken"]').val(),
},

(3) 通过获取返回的cookie中的字符串,放置在请求头中发送

# 引入一个 ajax_setup..js的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);
    }
  }
});
ajax_setup.js

注;

  • 如果使用从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

3.上传文件

  • HTML文件代码
    <body>
    <form action="" enctype="multipart/form-data"></form>
    <input type="file" name = f1>
    <button id="b1">上传</button>
    
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script src="/static/js/ajax_setup.js"></script>
    <script>
        $('#b1').click(function(){
            var form_obj = new FormData();
            form_obj.append('f1',$('[name="f1"]')[0].files[0])
    
            $.ajax({
                url:'/upload/',
                type:'post',
                processData:false,
                contentType:false,
                data:form_obj,
                success:function(){
                    alert(res)
                }
            })
        })
    </script>
    </body>
  • views.py代码
    from django.shortcuts import render,HttpResponse
    def upload(request):
        if request.is_ajax():
            file_obj = request.FILES.get("f1")
            with open(file_obj.name,'wb') as f:
                for i in file_obj.chunks():
                    f.write(i)
            return HttpResponse('上传成功')
        return render(request,'upload.html')

练习  用户名是否已被注册

  • html文件
    <body>
    username:<input  type="text" name="user"><span></span>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script src="/static/js/ajax_setup.js"></script>
    <script>
        $('[name="user"]').blur(function(){
            $.ajax({
                url:'/check/',
                type:'post',
                data:{
                    user:$('[name="user"]').val()
                },
                success:(res)=>{
                    $(this).next().text(res.status_content)
                }
            })
        }).focus(function(){
            $(this).next().text('')
        })
    </script>
    </body>
  • views.py
    from app01 import  models
    def register(request):
        return render(request, 'register.html')
    
    def check(request):
        # 获取到从页面提交的注册名
        register_name = request.POST.get('user')
        if not register_name:
            return JsonResponse({'status': 0, 'status_content': '用户名不能为空'})
        else:
            ret = models.User.objects.filter(name=register_name)
            if ret:
                return JsonResponse({'status': 0, 'status_content': '用户名已存在'})
            else:
                return JsonResponse({'status': 1, 'status_content': '用户名可以使用'})
  • urls
     url(r'^register/', views.register),
     url(r'^check/', views.check),
原文地址:https://www.cnblogs.com/wcx666/p/10104210.html