• 视图之Ajax、Json


    Ajax

    同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;

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

    AJAX(Asynchronous Javascript And XML):异步的Javascript和XML。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(现在更多使用json数据)。AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

    AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应。

    AJAX常见应用情景:搜索引擎根据用户输入的关键字,自动提示检索关键字;注册时候的用户名的查重,当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询用户是否存在。

    优点:

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

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

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

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

    <--login.html文件内容:--->
    {% load static %} <--加载静态文件-->
    ...
    <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' %}",  // url反向解析,重定向路径,避免写硬代码。注意加上引号。如果要直接写地址,如url:"/login/",第一个 / 若不写会直接和当前浏览器的地址进行拼接,如果写了会使用ID地址和端口号与之进行拼接。
                type:'post',            //post请求
                data:{username:$('#username').val(),pwd:$('#pwd').val(),csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val()},  //为后端传入数据

                success:function (data{   //data:后端返回的数据
                    data = JSON.parse(data);
                    if (data['status']){
                        location.href=data['home_url'];
                    }
                    else {
                        $('#error').text('用户名或者密码错误!')
                    }
                }
            })
        })
    </script>
    </body>
    ...

    <--base.html文件内容:-->
    ...
    <body>
    <h1>
        欢迎
    </h1>
    </body>
    ...
    # urls.py文件内容:
    path('login/', views.login,name='login'),
    path('home/', views.home,name='home'),


    # view.py文件内容:
    ...
    from django.http import JsonResponse
    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,content_type='application/json'# 直接返回字典格式是不可以的,必须转换成json字符串,需要改变响应头中的content类型,当前端ajax拿到数据后,通过data_type或者content_type发现发送来的是个json格式的数据,那么ajax就自动将这个数据反序列化得到了js的数据对象,然后通过对象可以直接操作数据。若不改变,则还需要在前端页面反序列化。
            else:
                res_dict['status'] = False
                return JsonResponse(res_dict) # JsonResponse自动dump数据和传递content_type类型。
    def home(request):
        return render(request,'base.html'

    ajax里面写$(this)时要注意:如果你想在不刷新页面的情况下来添加某些dom对象,并且这个对象也需要绑定事件的话,需要用on来给和他相同的标签对象来绑定事件。

    settings配置文件里面加上APPEND_SLASH=False:即当请求用户路径的时,不自动处理路径最后面的/,如果这个值为True,假如写了一个url为path('index/',views.test),当用户请求127.0.0.1:8000/index时,django会让浏览器重新再发一次请求,并且在这个路径后面加上/,即127.0.0.1:8000/index/,此时和我们的url就能匹配上了,如果设置成false,那么用户在输入127.0.0.1:8000/index,没有最后那个斜杠的路径时,就无法和url匹配上了。但是注意,django只能重定向让浏览器再发一个get请求,当用post方法提交数据的时,就像上面ajax里那个url必须和后端配置的url对应。

    Ajax的使用

    基于jQuery的实现

    <button class="send_Ajax">send_Ajax</button>
    <script>
           $(".send_Ajax").click(function(){
               $.ajax({
                   url:"",
                   type:""// POST/GET
                   data:{a:"a",b:"b"}, 
                   success:function(data){},

                   errorfunction (jqXHR, textStatus, err{},

                   completefunction (jqXHR, textStatus{},

                   statusCode: {
                        '403'function (jqXHR, textStatus, err{},

                        '400'function (jqXHR, textStatus, err{},
                       ......
                    }
               })
           })
    </script>

    ajax参数

    请求参数

    data:当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式(urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。

    processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;如果为false, 那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString(),最后得到一个[object,Object]形式的结果。

    contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,比如contentType:"application/json",即向服务器发送一个json字符串:注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象。

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

    响应参数

    dataType:预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;dataType的可用值:html|xml|json|text|script

    headers:自定制请求头。

    Ajax请求设置csrf_token

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

    $.ajax({
      data: {
        "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val()  // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中
      }
    })

    方式2

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

    方式3

    通过获取返回的cookie中的字符串放置在请求头中发送。 注意:需要引入一个jquery.cookie.js插件。

    <script src="{% static 'js/jquery.cookie.js' %}"></script>

    $.ajax({
    headers:{"X-CSRFToken":$.cookie('csrftoken')}, 
    })

    `content_type`:

    1. 响应头默认为:text/html; charset=utf-8

    2. 请求头默认为:application/x-www-form-urlencoded; charset=utf-8即向后端的请求格式为urlencoded,与GET请求提交数据的请求格式相同,但数据位置不同,GET请求数据放在urlhou,urlencoded数据放在了请求体中。数据发送至后端后,Django内部调用了内置的解析器(接口的十大组件之一)将其解析。

    3. 可在ajax中指定contentType类型:

     $.ajax({
                ...
                contentType:"`application/json"  //指定发送json格式
                 data:Json.stringify({"k":"1","k2":"2"})  // data参数中的键值对,如果值不为字符串,需要将其转换成字符串类型。
                success:function (data{}
    1. ContentType指的是请求体的编码类型,常见的类型共有3种:
    • application/x-www-form-urlencoded:浏览器的原生
      表单,如果不设置 enctype 属性,那么最终就会以默认格式application/x-www-form-urlencoded方式提交数据,ajax默认也是这个。
    • multipart/form-data:使用表单上传文件时,必须让 表单的 enctype 等于 multipart/form-data。
    • application/json:用来告诉服务端消息主体是序列化后的 JSON 字符串。
    1. 服务端接受到数据之后,通过contenttype类型的值来使用不同的方法解析数据,django不能解析contenttype值为json的数据格式,但可以解析application/x-www-form-urlencoded 和multipart/form-data,如果传json类型的数据,需要自己来写一个解析数据的方法。

    Django内置的serializers做序列化

    源码:

    def books_json(request):
        book_list = models.Book.objects.all()[0:10]
        from django.core import serializers
        ret = serializers.serialize("json", book_list)
        return HttpResponse(ret)

    Json

    JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation),但JSON 仍然独立于语言和平台,是轻量级的文本数据交换格式,具有自我描述性,更易理解。

    json数据类型和python数据类型的对比:

    json数据类型和python数据类型的对比
    json数据类型和python数据类型的对比

    上面的这几种数据类型进行json.dumps序列化之后都是字符串,注意是由单引号括起的,数据里面的单引号,序列化后会变成双引号。python中的datetime等时间日期类型、集合类型等是不能进行json序列化的,因为json没有对应的格式。

    import json
    from datetime import datetime
    from datetime import date

    # 对含有日期格式数据的json数据进行转换
    class JsonCustomEncoder(json.JSONEncoder):
        def default(self, field):
            if isinstance(field,datetime):
                return field.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(field,date):
                return field.strftime('%Y-%m-%d')
            else:
                return json.JSONEncoder.default(self,field)


    d1 = datetime.now()

    dd = json.dumps(d1,cls=JsonCustomEncoder)
    print(dd)

    不合格的json对象:

    name"张三"'age'32 }  // 属性名必须使用双引号
    [32641280xFFF// 不能使用十六进制值
    "name""张三""age"undefined }  // 不能使用undefined
    "name""张三",
      "birthday"new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
      "getName":  function({return this.name;}  // 不能使用函数和日期对象
    }

    // JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象 
    JSON.parse('{"name":"张三"}');
    JSON.parse('{name:"张三"}') ;   // 错误
    JSON.parse('[18,undefined]') ;   // 错误

    // JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。 
    JSON.stringify({"name":"张三"})

    JSON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁琐笨重的 XML 格式。JSON 格式书写简单;符合 JavaScript 原生语法,可以由解释引擎直接处理,不用另外添加解析代码。所以,JSON迅速被接受,已经成为各大网站交换数据的标准格式,并被写入ECMAScript 5,成为标准的一部分。

  • 相关阅读:
    虚拟机安装Linux方案和操作系统启动流程
    CentOS7防止root密码被破解
    子网划分和VLAN
    Python之包的相关
    禁止复制文本的代码 HTML
    asp.net中Session过期设置方法
    CSS+DIV问题!DIV的最小高度问题!
    设置COOKIE过期时间的方法
    网站常见问题及解决方法(div/css)
    ASP.NET中如何删除最近打开的项目和文件的记录
  • 原文地址:https://www.cnblogs.com/wby-110/p/13383071.html
Copyright © 2020-2023  润新知