• 07.django之Ajax


    一、关于Ajax

    # AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”
    # 即使用Javascript语言与服务器进行异步交互,传输的数据为XML
    # 传输的数据不只是XML,现在更多使用json数据
    """
    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
        a.同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
        b.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
    AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
    """

    1、Ajax示例

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

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="x-ua-compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>AJAX局部刷新实例</title>
    </head>
    <body>
    
    <input type="text" id="i1">+
    <input type="text" id="i2">=
    <input type="text" id="i3">
    <input type="button" value="AJAX提交" id="b1">
    
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script>
      $("#b1").on("click", function () {
        $.ajax({
          url:"/ajax_add/", //别忘了加双引号
          type:"GET",  
          data:{"i1":$("#i1").val(),"i2":$("#i2").val()}, //object类型,键值形式的,可以不给键加引号
          success:function (data) {
            $("#i3").val(data);
          }
        })
      })
    </script>
    </body>
    </html>
    ajax_demo1.html
    def ajax_demo1(request):
        return render(request, "ajax_demo1.html")
    
    
    def ajax_add(request):    #time.sleep(10)  #不影响页面发送其他的请求
        i1 = int(request.GET.get("i1"))
        i2 = int(request.GET.get("i2"))
        ret = i1 + i2
        return JsonResponse(ret, safe=False)    #return render(request,'index.html')  #返回一个页面没有意义,就是一堆的字符串,拿到了这个页面,你怎么处理,你要做什么事情,根本就没有意义
    views.py
    urlpatterns = [
        ...
        url(r'^ajax_add/', views.ajax_add),
        url(r'^ajax_demo1/', views.ajax_demo1),
        ...   
    ]
    urls.py

    2、Ajax应用场景

    """
    1.注册时用户名查重
    (当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,
    然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。)
        整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
        当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
    当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,
    服务器会查询名为kkkkk的用户是否存在,最终服务器返回true表示名为kkkkk的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”
    2.搜索引擎用户输入关键字,自动提示检索关键字
    """

    3、Ajax的优缺点

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

    4、示例2:

    写一个登陆认证页面,登陆失败不刷新页面,提示用户登陆失败,登陆成功自动跳转到网站首页。

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <div>
        用户名:<input type="text" id="username">
        密码:<input type="text" id="pwd">
        {% csrf_token %}
        <button id="sub">提交</button>
        <span style="color: red;font-size: 12px;" id="error"></span>
    </div>
    
    <script src="{% static 'jquery.js' %}"></script>
    
    <script>
        $('#sub').click(function () {
            $.ajax({
                url:"{% url 'login' %}",
                type:'post',
                data:{username:$('#username').val(),pwd:$('#pwd').val(),csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val()},
    
                success:function (data) {
                    data = JSON.parse(data);
                    console.log(data,typeof data);
                    if (data['status']){
    
                        location.href=data['home_url'];
                    }
                    else {
                        $('#error').text('用户名或者密码错误!')
                    }
                }
    
            })
    
    
        })
    
    
    
    </script>
    
    </body>
    </html>
    login.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <h1>
        欢迎来到xxx官网
    </h1>
    </body>
    </html>
    base.html
    url(r'^login/', views.login,name='login'),
    url(r'^home/', views.home,name='home'),
    urls.py
    def login(request):
        res_dict = {'status':None,'home_url':None}
        if request.method == 'GET':
            return render(request,'login.html')
        else:
            uname = request.POST.get('username')
            pwd = request.POST.get('pwd')
    
            user_obj = models.UserInfo.objects.filter(name=uname,password=pwd).exists()
            import json
            if user_obj:
    
                res_dict['status'] = True
                res_dict['home_url'] = reverse('home')
                res_json_dict = json.dumps(res_dict)
    
                return HttpResponse(res_json_dict) #直接回复字典格式是不可以的,必须转换成json字符串,转换成普通字符串也是不行的,因为前端需要对json进行反序列获得这个字典,在通过字典的形式来操作数据。
            else:
                res_dict['status'] = False
                res_json_dict = json.dumps(res_dict)
                return HttpResponse(res_json_dict)
          # 如果你就是不使用JsonResponse的话,也可以给HttpResponse添加一个参数,content_type='application/json',那么前端ajax拿到数据之后,也是不需要反序列化的,ajax的回调函数就收到的就是一个反序列化之后的一个对象,因为ajax接受到数据后,通过这个data_type或者content_type发现你发送来的是个json格式的数据,那么ajax内容就自动将这个数据反序列化得到了js的数据对象,然后通过对象可以直接操作数据。      # return HttpResponse(res_json_dict,data_type='application/json')      # return JsonResponse(res_dict)
    def home(request):
    
        return render(request,'base.html')
    views.py

    二、Ajax详解

    1、基于jQuery的实现

    <button class="send_Ajax">send_Ajax</button>
    <script>
    
           $(".send_Ajax").click(function(){
    
               $.ajax({
                   url:"/handle_Ajax/",
                   type:"POST",
                   data:{username:"chao",password:123},
                   success:function(data){
                       //接收的是请求成功获取到的相应结果
                       console.log(data)
                   },
                   
                   error: function (jqXHR, textStatus, err) {
                            //接收的是请求失败获取到的相应结果,根据响应码相应什么样的信息
                            console.log(arguments);
                        },
    
                   complete: function (jqXHR, textStatus) {
                   //与 ajaxSuccess() 不同,通过 ajaxComplete() 方法规定的函数会在请求完成时运行,即使请求并未成功。
                            console.log(textStatus);
                    },
    
                   statusCode: {
                        '403': function (jqXHR, textStatus, err) {
                              console.log(arguments);
                         },
    
                        '400': function (jqXHR, textStatus, err) {
                            console.log(arguments);
                        }
                    }
    
               })
    
           })
    
    </script>   

    2、基于原生js实现

    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=chao&password=123456");
        xmlHttp.onreadystatechange = function () {
          if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
            alert(xmlHttp.responseText);
          }
        };
      };

    3、ajax参数

    3.1、data

    """
    data:
    当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式
    (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。
    """ 
              function testData() {
                   $.ajax("/test",{     //此时的data是一个json形式的对象
                      data:{
                        a:1,
                        b:2
                      }
                   }); 
    processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false,
                 那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString()
                 ,最后得到一个[object,Object]形式的结果。

    3.2、contentType

    """
    默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
    用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,
    比如contentType:"application/json",即向服务器发送一个json字符串
    """
                $.ajax("/ajax_get",{
                 
                      data:JSON.stringify({
                           a:22,
                           b:33
                       }),
                       contentType:"application/json",
                       type:"POST",
                 
                   });                          //{a: 22, b: 33}
    
                 注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象
    
                 views.py:   json.loads(request.body.decode("utf8"))

    3.3、traditional

    # 一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]},
    # traditional为false会对数据进行深层次迭代;

    3.4、服务器相应参数

    """
    预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
    默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;
    比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容
    进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式
    的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用data Type
    dataType的可用值:html|xml|json|text|script
    """

    三、Ajax请求设csrf_token

    方式1:通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。

    $.ajax({
      url: "/cookie_ajax/",
      type: "POST",
      data: {
        "username": "chao",
        "password": 123456,
        "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val()  // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中
      },
      success: function (data) {
        console.log(data);
      }
    })

    方式2:

    $.ajaxSetup({
        data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
    });

    方式3:通过jquery

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

    注意:需要引入一个jquery.cookie.js插件。

    <script src="{% static 'js/jquery.cookie.js' %}"></script>
    
    $.ajax({
     
    headers:{"X-CSRFToken":$.cookie('csrftoken')}, #其实在ajax里面还有一个参数是headers,自定制请求头,可以将csrf_token加在这里,我们发contenttype类型数据的时候,csrf_token就可以这样加
     
    })

    ------------------

    ------------------

    -------------------

  • 相关阅读:
    打理自己的生活
    多线程练习 -- 自定义NSOperation
    多线程练习 -- 单例设计模式
    IOS学习笔记 -- 多线程
    画画板 -- 可自定义线的宽度和颜色
    手势识别器基本练习
    触摸事件练习 -- 手势解锁
    触摸事件练习 -- 画画板(截屏分类)
    Main.storyboard
    Quartz2D练习 -- 裁剪图片分类
  • 原文地址:https://www.cnblogs.com/kongxiangqun/p/13708259.html
Copyright © 2020-2023  润新知