zoukankan      html  css  js  c++  java
  • 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() 
  • 相关阅读:
    Java安全之JNDI注入
    Visual Studio 2019 升级16.8之后(升级.Net 5),RazorTagHelper任务意外失败
    .Net Core 3.1升级 .Net 5后出现代码错误 rzc generate exited with code 1.
    重走py 之路 ——普通操作与函数(三)
    重走py 之路 ——字典和集合(二)
    设计模式结(完结篇)
    重走py 之路 ——列表(一)
    RestfulApi 学习笔记——分页和排序(五)
    RestfulApi 学习笔记——查询与过滤还有搜索(五)
    Android开发 Error:The number of method references in a .dex file cannot exceed 64K.Android开发 Error:The number of method references in a .dex file cannot exceed 64K
  • 原文地址:https://www.cnblogs.com/fdsimin/p/13368349.html
Copyright © 2011-2022 走看看