• Ajax基本使用和JsonHttpResponse


    Ajax : 异步请求,不会刷新页面,页面上用户之前输入的数据都不会丢失。

    简单请求案例:

    views页面

    from django.shortcuts import render,HttpResponse,redirect
    from django.urls import reverse
    def login(request):
        if request.method == "POST":
            if request.POST.get("uname") == "root":
                return HttpResponse("ok")
            return HttpResponse("error")
        return render(request, "login.html")
    
    def home(request):
    
        return render(request,"home.html")

    HTML页面

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <div>
        <label>
            用户名: <input type="text" name="username" id="username">
        </label>
        <label>
            密码: <input type="password" name="password" id="password">
        </label>
        <button id="btn">提交</button>
        <span style="color: red;font-size: 12px" id="err"></span>
    </div>
    
    </body>
    <script src="{% static 'js/jquery.js' %}"></script>
    <script>
        $('#btn').click(function (){
            var name = $('#username').val();
            var pwd = $('#password').val();
            console.log(name,pwd)
            $.ajax({
                url: {% url 'login' %}',
                type: 'post',
                data: {uname:name,upwd:pwd},
                success: function (res) {
                    console.log(res, typeof res)
                    if(res==="ok"){
                        location.href = '{% url 'home' %}';
                    }
                    else{$('#err').text("用户名或者密码错误")
    
                    }
                }
            })
    
        })
    </script>
    
    </html>

    注意点:

    $.ajax({  //
      url:'/login_ajax/',  //写路径时,如果后台使用的是django框架,那么url路径的后面的斜杠要加上,如果想不加上斜杠,
    那么需要在django的settings配置文件中加上 APPEND_SLASH = False,并且后台的urls.py文件中的路径要和ajax请求路径对应好,
    该有斜杠写斜杠,不需要斜杠的,去掉斜杠 type:'post', ... }),

    在js代码中使用url别名反向解析来写路径:

    $.ajax({  //
      url:'{% url "login_ajax" %}',
      type:'post',
      ...
    }),
    但是,要注意一点,当这段js代码是写到某个js文件中,然后hmtl文件通过script标签的src属性来引入时,
    {% url "login_ajax" %}语法就不能被模板渲染了,也就是失效了

    响应字典数据类型

    方式一: 手动利用json序列化和反序列化

    views页面

    from django.shortcuts import render,HttpResponse,redirect
    from django.urls import reverse
    from django.http import JsonResponse
    def login(request):
        if request.method == "POST":
            if request.POST.get("uname") == "root":
                return HttpResponse("ok")
            return HttpResponse("error")
        return render(request, "login.html")
    
    def home(request):
        return render(request,"home.html")
    
    def data(request):
        import json
        dic = {"summer":["夏日惊喜","西瓜","哈密瓜","凉面"]}
        dic_str = json.dumps(dic,ensure_ascii=False)
        return HttpResponse(dic_str)

    HTML页面

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>这是home页面</h1>
    <button id="btn_home">点击有惊喜</button>
    <ul>
    
    </ul>
    </body>
    <script src="{% static 'js/jquery.js' %}"></script>
    <script>
        $('#btn_home').click(function () {
            $.ajax({
                url: '{% url "data" %}',
                type: 'get',
                success: function (res) {
                    console.log(res, typeof res) // 夏天 string  用HttpResponce传递字典数据, 只能取到字典的键
                    // 引入json模块后得到字符串形式的字典: {"summer": ["西瓜", "哈密瓜", "凉面"]} string
                    var dic_res = JSON.parse(res)
                    console.log(dic_res,typeof dic_res)
                    var ret = dic_res.summer
                    // 将列表中的内容放到页面中
                    for (var i=0;i<ret.length;i++){
                       var content = ret[i];
                        var liEle = document.createElement('li');
                        liEle.innerText = content
                        $('ul').append(liEle);
    
                    }
                }
            })
        })
    </script>
    
    </html>


    # 第一种方式,直接通过HttpResponse回复字典数据,那么ajax接受到数据之后,需要自行反序列化
    # data_list_str = json.dumps(data_list, ensure_ascii=False)
    # 直接使用HttpResponse回复字典类型数据,那么会将字典里面元素的键都拼接成一个字符串来响应,所以不是我们想要的结果,所以我们先将字典类型数据,转换成json字符串,在通过HttpResponse来进行响应

    方式二: 手动加响应头键值对 ['content-type'] = 'application/json'

    # data函数改写
    def data(request):
        import json
        dic = {"summer":["夏日惊喜","西瓜","哈密瓜","凉面"]}
        dic_str = json.dumps(dic,ensure_ascii=False)
        ret = HttpResponse(dic_str)
        ret['content-type'] = 'application/json'
        return ret
    
    
    # HTML接收和显示数据修改
    success: function (res) {
                    console.log(res, typeof res) // 夏天 string  用HttpResponce传递字典数据, 只能取到字典的键
                    // 引入json模块后得到字符串形式的字典: {"summer": ["西瓜", "哈密瓜", "凉面"]} string
                    {#var dic_res = JSON.parse(res)#}
                    {#console.log(dic_res,typeof dic_res)#}
                    var ret = res.summer
                    // 将列表中的内容放到页面中
                    for (var i=0;i<ret.length;i++){
                       var content = ret[i];
                        var liEle = document.createElement('li');
                        liEle.innerText = content
                        $('ul').append(liEle);


    #第二种方式:通过HttpResponse回复字典数据,回复之前,加上一个响应头键值对,如下,那么ajax收到这个响应数据的时候,
    会查看这个响应头,发现content-type这个响应头的值为application/json,那么会自动对响应数据进行反序列化,不需要我们自己手动反序列化了

    方式三: 引入JsonHttpResponce

    # data部分
    from django.http import JsonResponse
    def data(request):
        import json
        dic = {"summer":["夏日惊喜","西瓜","哈密瓜","凉面"]}
        # dic_str = json.dumps(dic,ensure_ascii=False)
        # ret = HttpResponse(dic_str)
        # ret['content-type'] = 'application/json'
        return JsonResponse(dic)
    #JsonResponse:1 序列化数据   2 加上['content-type'] = 'application/json'这个响应头键值对

    注意:

    lst = ["夏日惊喜","西瓜","哈密瓜","凉面"]
        #当使用JsonResponse回复非字典类型数据时,需要将safe参数的值改为False, 不然会报错
        return JsonResponse(lst, safe=False)

    局部更新数据案例:

    views页面

    def sub(request):
        if request.method == "GET":
            return render(request,"sub.html")
        else:
            import json
            print(request.body)
            data = request.body.decode()
            print(data)
            data = json.loads(data)
            print(data)
            a = int(data["a"])
            b = int(data["b"])
            ret = a+b
            print(ret)
            return HttpResponse(ret)

    HTML页面

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <label>
        a: <input type="text" name="a" id="aid">
    </label>
    <label>
        b: <input type="text" name="b" id="bid">
    </label>
    <button id="btn_sub">查询</button>
    <br>
    a+b= <span id="sp" style="color: burlywood"></span>
    
    </body>
    <script src="{% static 'js/jquery.js' %}"></script>
    <script>
    
        $('#btn_sub').click(function () {
            var a = $('#aid').val();
            var b = $('#bid').val();
            $.ajax({
                url: '{% url 'sub' %}',
                type: 'post',
                headers: {
                    'Content-Type':'application/json',
                },
                data: JSON.stringify({a:a,b:b}),
                success: function (res) {
                    {#alert(res);#}
                    $('#sp').text(res)
                }
            })
        })
    </script>
    </html>

    请求头消息格式分析

    请求消息格式和请求方法没有关系, 和请求头键值对中的这一组键值对有关系

    file说明    <!-- enctype="multipart/form-data"这个参数就是将本次请求的消息格式,也就是那个content-type的值改为multipart/form-data,
    那么本次http请求,会将文件数据片段发送 -->

    Content-Type: application/x-www-form-urlencoded; //浏览器发送数据ajax或者form表单,默认的格式都是它 它表示请求携带的数据格式,application/x-www-form-urlencoded对应的数据格式是:a=1&b=2
    '''
    socket 接收到我们请求数据,会分析一下Content-Type: application/x-www-form-urlencoded;这个请求头

    # 叫做解析器
    if Content-Type == 'application/x-www-form-urlencoded':
    data = 'a=1&b=2'
    l1 = data.split('&') [a=1,b=2]
    for i in l1:
    k,v = i.split('=')
    if 请求方法 == 'GET':
    request.GET[k] = v

    elif Content-Type == 'multipart-formdata':
    request.FILES

    #django没有内置对appcation/json的消息格式的解析器,所以如果请求数据是json类型,那么我们需要自行解析

    '''

    ajax结合sweetalert删除数据案例:

    views页面

    class Del_book(View):
        def get(self,request,pk):
            try:
                models.Book.objects.get(id=pk).delete()
            except:
                return HttpResponse('没有这本书的信息',status=404)
            # return HttpResponse('error') #默认响应的状态码都是200
            return HttpResponse('ok')

    HTML页面

    {% load static %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
        <link rel="stylesheet" href="{% static 'bootstrap-sweetalert-master/dist/sweetalert.css' %}">
    </head>
    <body>
    <div class="container">
        <h1>书籍展示</h1>
        <div class="row">
            <div class="clo-md-8 col-md-offset-2">
                <a href="{% url 'add_book' %}" class="btn btn-primary" style="margin-bottom: 10px">添加书籍</a>
                <table class="table table-bordered table-hover table-striped">
                    <thead>
                    <tr>
                        <th>编号</th>
                        <th>书名</th>
                        <th>价格</th>
                        <th>出版日期</th>
                        <th>出版社</th>
                        <th>作者</th>
                        <th>操作</th>
                    </tr>
                    </thead>
    
                    <tbody>
                    {% for each_book in book_obj %}
                        <tr>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ each_book.title }}</td>
                            <td>{{ each_book.price }}</td>
                            <td>{{ each_book.pub_date|date:'Y-m-d' }}</td>
                            <td>{{ each_book.pud.name }}</td>
                            <td>{{ each_book.author_name }}</td>
                            <td>
                                <a href="{% url 'update_book' each_book.id %}" class="btn btn-warning">编辑</a>
                                <span class="id_num hidden">{{ each_book.id }}</span>
                                <button class="btn btn-danger">删除</button>
                            </td>
                        </tr>
                    {% endfor %}
    
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    
    
    </body>
    <script src="{% static 'js/jquery.js' %}"></script>
    <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
    <script src="{% static 'bootstrap-sweetalert-master/dist/sweetalert.min.js' %}"></script>
    
    <script>
    
        $(".btn-danger").on("click", function () {
            var delete_id = $(this).prev().text()
            var ths = $(this)  //因为下面的函数中this指向的不是我们的标签按钮,所以通过一个变量来保存一下这个$(this),方便后面使用
            swal({
                    title: "are you sure?",
                    text: "要谨慎!",
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonClass: "btn-danger",
                    confirmButtonText: "确定删除",
                    cancelButtonText: "容我三思",
                    closeOnConfirm: false
                },
                (function () {
                    $.ajax({
                        url: '/del_book/' + delete_id + '/',
                        type: 'get',
                        success: function (res) {
                            //当状态码为2xx或者3xx时才认为是请求正常成功了,会触发success对应的函数。但是当状态为4xx、5xx的时候,ajax认为此次请求是失败的会触发error属性对应的函数
                            if (res === "ok") {
                                swal("删除成功!", "success");  //关闭弹框
                                ths.parents('tr').remove()  //删除页面上对应的数据
                            }
    
                        },
                        error: function (res) {
                            if (res.status === 404) {
                                console.log(res.responseText)
                                //res.responseText是后台响应回来的错误信息
                                swal("删除失败!", res.responseText, "error")
                            }
                        }
                    })
    
                }));
        })
    </script>

    箭头函数:

    普通函数:var k = function(参数){return 'kkkk'};
    箭头函数:var k = (参数) =>{return 'kkkk'};
    箭头函数简写: var k = (参数)=>'kkkk'

    js函数中this的指向问题

    var a = 'xx';
    var d1 = {
      a:'ss',
      f: () => {
        //this指向函数调用者
        // console.log(this);
        console.log(this.a);
      }
    }
    d1.f()  #调用者是d1对象,所以打印的内容为ss
    
    # 函数的单体模式
    var a = 'xx';
    var d1 = {
      a:'ss',
      f(){
        console.log(this.a);  //结果为:ss
      },
    }
    d1.f()  
    
    # 箭头函数,改变this的指向,将this指向上下文的this
    var a = 'xx';
    var d1 = {
      a:'ss',
      f:()=>{
        
                console.log(this); // 指向了Window对象
            console.log(this.a);  //结果为xx
        
        f1()
      },
    }
    d1.f() 
    
    
    //
    var a = 'xx';
    var d1 = {
      a:'ss',
      f:function(){
            console.log(this.a); // ss
          function f1(){
            console.log(this); // 指向了Window对象
            console.log(this.a);  //结果为xx
          }
          f1() 
      },
    }
    d1.f() 
    
    //箭头函数改变this指向
    var a = 'xx';
    var d1 = {
      a:'ss',
      f:function(){
            console.log(this.a); // ss
          var f1 = ()=>{
            console.log(this); // 指向了d1对象
            console.log(this.a);  //结果为ss
          }
          f1() 
      },
    }
    d1.f() 
    
    //箭头函数改变this指向
    var a = 'xx';
    var d1 = {
      a:'ss',
      f:()=>{
            console.log(this.a); // xx
          var f1 = ()=>{
            console.log(this); // 指向了window对象
            console.log(this.a);  //结果为xx
          }
          f1() 
      },
    }
    d1.f() 
  • 相关阅读:
    06深入理解C指针之---指针操作和比较
    05深入理解C指针之---指针声明和解引
    04深入理解C指针之---指针优缺点
    03深入理解C指针之---变量与内存
    iOS UIWebView获取403/404
    控制动画时间
    控制动画时间
    iOS中消息的传递机制
    iOS中消息的传递机制
    HTML5能取代Android和iOS应用程序吗?
  • 原文地址:https://www.cnblogs.com/fdsimin/p/13368349.html
Copyright © 2020-2023  润新知