zoukankan      html  css  js  c++  java
  • python-day81--Ajax

    一、准备知识:json

    1.什么是json?

      JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。任何的语言之间都可以用json进行数据的交换

    2、回顾json的dumps和loads方法

    import json
    
    ##json序列化##
    d={"name":"egon","age":12}
    
    data=json.dumps(d)
    
    print(data)        #{"name": "egon", "age": 12}
    print(type(data))     #<class 'str'>
    f=open("a.txt","w")
    
    f.write(data)
    f.close()
    
    ## 反序列化##
    
    f=open("b","r")
    
    data=f.read()
    data=json.loads(data)
    print(data)      #{'name': 'Yuan'}
    print(type(data))    #<class 'dict'>
    View Code

    3、json字符串概念

    i=10
    s='hello'
    l=[111,222,333]
    b=True
    t=(1,2,3)
    d={'name':'yuan'}
    
    print(json.dumps(i))    #    '10'    json 字符串
    print(json.dumps(s))    #    '"hello"'
    print(json.dumps(l))    #    '[111, 222, 333]'
    print(json.dumps(t))    #    '[1, 2, 3]'
    print(json.dumps(d))    #    '{"name": "yuan"}'
    print(json.dumps(b))    #    '{"name": "yuan"}'

    4、json对象概念

    json对象是JS的对象子集,并且json对象只认双引号

    不合格的json对象

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

    5、stringify与parse方法

    python中json模块有dumps和loads方法,而在js语言中有stringify与parse方法

    JSON.parse():     用于将一个 JSON 字符串转换为 JavaScript 对象 
    eg:
    console.log(JSON.parse('{"name":"Yuan"}'));
    console.log(JSON.parse('{name:"Yuan"}')) ;   // 错误
    console.log(JSON.parse('[12,undefined]')) ;   // 错误
    
    
    JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。 
    eg:  console.log(JSON.stringify({'name':"egon"})) ;
        <script>
    
            //  JS 的json序列化与反序列化方法
    
            //  parse()
            s='{"name":1}';
            var data=JSON.parse(s);
            console.log(data);
            console.log(typeof data);   //object
    
            // stringfy
    
            s2={'name':'yuan'};
            console.log(JSON.stringify(s2))    // '{"name":"yuan"}'
            console.log(typeof JSON.stringify(s2));   //string
    
        </script>
    View Code

    6、如在读取json数据时,数据过长不好浏览时,可用bejson工具查看

    二、Ajax简介

    AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。
    功能:是JS的一种向后端服务器发送数据技术,也就是说在js语言中使用,写在js文件中,或者<script>标签中

    AJAX的特点

     -  异步处理

     -  局部刷新

    三、jquery实现的ajax

    注意:         var btn=$(this)           //在ajax中不能直接用$(this) ,因为作用域不一样  ,所以在这里先赋值给一个变量,然后用变量

    <!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>Title</title>
    </head>
    <body>
    
    <a href="/get_OK/">点击</a><span class="error"></span>
    <hr>
    <p>姓名<input type="text"></p>
    <p>密码<input type="password"></p>
    <p><button class="Ajax_send">Ajax_send</button><span class="login_error"></span></p>
    
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
    <script>
        $(".Ajax_send").click(function () {
            // ajax请求
    
            $.ajax({
                url:"/get_ajax/",       //请求路径
                type:"GET",            //请求方式
                data:JSON.stringify({      //请求数据
                   name:$(":text").val(),
                   pwd:$(":password").val()
                }),    // 请求数据 ,是js数据    ?name=yuan&pwd=123
                contentType:"application/json",  
                
                //不指定请求类型时
    {#            data:{                                #}
    {#               name:$(":text").val(),             #}
    {#               pwd:$(":password").val()           #}
    {#            },                                    #}
                success:function (data) {           //data是形参
                    var data=JSON.parse(data);
                    console.log(data);
                    console.log(typeof data);
                    // $(".error").html(data)        找到span标签,加上数据
    
                    if(!data["flag"]){                   //如果验证错误
                        $(".login_error").html("用户名或者密码错误")
                    }
                }
            })
        })
    </script>
    </body>
    </html>
    --------------urls.py
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^get_ajax/', views.get_ajax),
    ]
    
    
    --------------views.py 
    
    #不指定传输数据的类型时
    def get_ajax(request):
    
        username=request.GET.get("name")
        password=request.GET.get("pwd")
    
        response={"flag":False}
        if username=="yuan" and password=="123":
            response["flag"]=True
        import json
        import time
    
        time.sleep(10)   #验证异步的特点
        return HttpResponse(json.dumps(response))


    get/post两种方式分别发送默认编码 urlencode 和 json 格式的数据

    ---------------------views.py
    
    def asd(request):
        print(request.GET)
        print(request.POST)
        print(request.body)
    
        return HttpResponse('OK')
    
    ---------------------.html
    
        $.ajax({
            url:/asd/,
            type:'get',
            data:{
                           a:22,
                           b:33
                       },
            success:function () {
                alert(222)
            }
        })
    
    结果:
    <QueryDict: {'a': ['22'], 'b': ['33']}>
    <QueryDict: {}>
    b''
    ---------------------views.py
    
    def asd(request):
        print(request.GET)
        print(request.POST)
        print(request.body)
    
        return HttpResponse('OK')
    
    ---------------------.html
    
    $.ajax({
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            url:/asd/,
            type:'get',
            data:JSON.stringify({
                           a:22,
                           b:33
                       }),
            contentType:"application/json",
    
            success:function () {
                alert(222)
            }
        })
    
    结果:
    <QueryDict: {'{"a":22,"b":33}': ['']}>
    <QueryDict: {}>
    b''
    ---------------------views.py
    
    def asd(request):
        print(request.GET)
        print(request.POST)
        print(request.body)
    
        return HttpResponse('OK')
    
    ---------------------.html
    $.ajax({
            url:/asd/,
            type:'post',
            data:{
                           a:22,
                           b:33
                       },
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            success:function () {
                alert(222)
            }
        })
    
    结果:
    <QueryDict: {}>
    <QueryDict: {'a': ['22'], 'b': ['33']}>
    b'a=22&b=33'
    ---------------------views.py
    
    def asd(request):
        print(request.GET)
        print(request.POST)
        print(request.body)
    
        return HttpResponse('OK')
    
    ---------------------.html
    $.ajax({
            url:/asd/,
            type:'post',
            data:JSON.stringify({
                           a:22,
                           b:33
                       }),
            contentType:"application/json",
            headers:{"X-CSRFToken":$.cookie('csrftoken')},
            success:function () {
                alert(222)
            }
        })
    
    结果:
    <QueryDict: {}>
    <QueryDict: {}>
    b'{"a":22,"b":33}'

    结论:所以无论用那种请求方式或者发送的什么数据,首先在视图函数中先打印一下GET、POST、body,看结果后再取值

    PS: 
      request.body # 一定有值
      request.POST # application/x-www-form-urlencoded/数据格式 :name=alex&age=123
      

          #
    方式一: $.ajax({ url:'xx', type:'post', data: JSON.stringfy(pList), headers:{'Content-Type':'application/json'}, //contentType:'json', success:function(arg){ } }) # 使用request.body取值 json.loads(request.body.decode('utf-8')) # 方式二: $.ajax({ url:'xx', type:'post', data: {k1: JSON.stringfy(pList),'age':18} // k1="[....]"&age=18 success:function(arg){ } }) # 使用request.post取值 json.loads(request.POST.get('k1'))

    1.    $.ajax参数

    请求参数:

    ######################------------data---------################
    
           data: 当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式
                 (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。
    
                 function testData() {
                   $.ajax("/test",{     //此时的data是一个json形式的对象
                      data:{
                        a:1,
                        b:2
                      }
                   });                   //?a=1&b=2
    ######################------------processData---------################
    
    processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false,
                 那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString()
                 ,最后得到一个[object,Object]形式的结果。
                
    ######################------------contentType---------################
    
    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对象
             $.ajax({
                  url: ""    ,    // 请求路径
                  type:""    ,    // 请求方式
             data:{"name":"yuan"} //请求数据
                 if  processData=false: //不对数据做预处理,不涉及编码类型
                 if  processData=true:
                        设计编码类型:
                  contentType:默认值: "application/x-www-form-urlencoded" success:function(data){      // data形参
    } })

     注意点

    data:JSON.stringify({
           a:22,
           b:33
       }),
    contentType:"application/json",
    type:"POST",
    当指定contentType是json时,data内的数据一定要转成json字符串,并且当是post请求时  csrf_token 要用header的方式传送,因为你在data内手动添加键值对的方式
    在指定contentType时,ajax不会按照默认的urlencode的方式做处理了,那就不会解析出csrf的数据了,故被forbidden

    响应参数

    dataType:  客户端期望服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
                默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;
                比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容
                进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式
                的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用data Type。
                dataType的可用值:html|xml|json|text|script
                见下dataType实例
    from django.shortcuts import render,HttpResponse
    from django.views.decorators.csrf import csrf_exempt
    # Create your views here.
    
    import json
    
    def login(request):
    
        return render(request,'Ajax.html')
    
    
    def ajax_get(request):
    
        l=['alex','little alex']
        dic={"name":"alex","pwd":123}
    
        #return HttpResponse(l)      #元素直接转成字符串alexlittle alex
        #return HttpResponse(dic)    #字典的键直接转成字符串namepwd
        return HttpResponse(json.dumps(l))
        return HttpResponse(json.dumps(dic))# 传到前端的是json字符串,要想使用,需要JSON.parse(data)
    
    //---------------------------------------------------
        function testData() {
    
            $.ajax('ajax_get', {
               success: function (data) {
               console.log(data);
               console.log(typeof(data));
               //console.log(data.name);
               //JSON.parse(data);
               //console.log(data.name);
                                         },
               //dataType:"json",
                                }
                           )}
    
    注解:Response Headers的content Type为text/html,所以返回的是String;但如果我们想要一个json对象
        设定dataType:"json"即可,相当于告诉ajax方法把服务器返回的数据转成json对象发送到前端.结果为object
        当然,
            return HttpResponse(json.dumps(a),content_type="application/json")
    
        这样就不需要设定dataType:"json"了。
        content_type="application/json"和content_type="json"是一样的!
    View Code

    2.csrf跨站请求伪造

       方式1

    $.ajaxSetup({
        data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
    });
    在使用ajax前配置此配置,但是这种方法有局限性,只有此配置和要返回的html文件在用一个文件内才起作用,如在插件内使用不起作用

       方式2

      {% csrf_token %}    
      ...
      ...


    $.ajax({

      data:{     "csrfmiddlewaretoken":'4PoazPJ2ZfCcoogiCmCLrsl0TmMQheDxrk0mKHJ9KwfbN1zFbdp6C890mU8xfU6y'
        ...
        ...   },
    })

    在页面内添加  {% csrf_token %} ,并且在ajax 的data中添加新的键值对

       方式3

    <script src="{% static 'js/jquery.cookie.js' %}"></script> 
    
    $.ajax({ 
    headers:{"X-CSRFToken":$.cookie('csrftoken')},
    })

    引用js/jquery.cookie.js文件或cdn,在ajax之前配置此配置,此方法100%有效

    3.  jQuery.serialize()

      3.1 serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串

      serialize()函数常用于将表单内容序列化,以便用于AJAX提交。

      该函数主要根据用于提交有效表单控件的name和value,将它们拼接为一个可直接用于表单提交的文本字符串,该字符串已经过标准的URL编码处理(字符集编码为UTF-8)。

      该函数不会序列化不需要提交的表单控件,这和常规的表单提交行为是一致的。例如:不在<form>标签内的表单控件不会被提交、没有name属性的表单控件不会被提交、带有disabled属性的表单控件不会  被提交、没有被选中的表单控件不会被提交。

    与常规表单提交不一样的是:常规表单一般会提交带有name的按钮控件,而serialize()函数不会序列化带有name的按钮控件。

      3.2 语法:找到要序列化的表单→  .serialize()

           data:$('#s1').serialize()

      3.3 返回值

      serialize()函数的返回值为String类型,返回将表单元素编码后的可用于表单提交的文本字符串。

      3.4  可以对表单内的所有数据都进行序列化,也可以对部分数据序列化

      $(":text, select, :checkbox").serialize()

    四、上传文件

    1. form表单实现的上传文件

    <form action="/upload/" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <p>用户名<input type="text" name="user"></p>
        <p>头像<input type="file" name="avatar"></p>
        <input type="submit">
    </form>
    
    
    -----------------------------
    def upload(request):
        if request.method=="POST":
            print("POST", request.POST)   #POST <QueryDict: {'csrfmiddlewaretoken': ['wwOnWaSQRIHiczZvmOG5ApqLv4Y8EPDMcFG5Tmevk9NNWoHD4zbxiX0TW9NL4kGE'], 'user': ['asd']}>
            print("FILES",request.FILES)  # FILES <MultiValueDict: {'avatar': [<InMemoryUploadedFile: 111111.png (image/png)>]}>
    
            file_obj=request.FILES.get("avatar")
            print(file_obj,type(file_obj))       #111111.png <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>   
            print(file_obj.name,"-----")  #111111.png -----
            with open(file_obj.name,"wb") as f:
                for i in file_obj:     
                    f.write(i)
    
            return HttpResponse("成功")
        return render(request,"upload.html")

    2.Ajax(FormData) 实现的上传文件

    使用FormData的最大优点就是我们可以异步上传一个二进制文件.

    代码部分:

    <!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>Title</title>
        <style>
            .login_error{
                color: red;
            }
        </style>
    </head>
    <body>
    
    
    
    
    <form action="" id="s1">
        <p>姓名<input type="text"></p>
        <p>密码<input type="password"></p>
        <p>头像<input type="file" id="upload_avatar"></p>
    </form>
    
    <p><button class="Ajax_send">Ajax_send</button><span class="login_error"></span></p>
    
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
    <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
    
    <script>
         function foo() {
            $(".login_error").html("")
        }
        $(".Ajax_send").click(function () {
    
            var formData=new FormData();
            formData.append("username",$(":text").val());
            formData.append("password",$(":password").val());
            formData.append("avatar",$("#upload_avatar")[0].files[0]);
            
            //$("#upload_avatar")[0].files[0]==File {name: "1.png", lastModified: 1508844386855, lastModifiedDate: Tue Oct 24 2017 19:26:26 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 286658, …}
            
            // ajax请求
            $.ajax({
                url:"/get_ajax/",
                type:"POST",
                headers:{"X-CSRFToken":$.cookie('csrftoken')},
    data:formData, contentType:false, processData:false,

    success:function (data) { var data
    =JSON.parse(data); console.log(data); console.log(typeof data); //object if(!data["flag"]){ $(".login_error").html("用户名或者密码错误") setTimeout(foo,3000) } } }) }) </script> </body> </html>
    def get_ajax(request):
    
        username=request.POST.get("username")
        password=request.POST.get("password")
        print("FIFLE",request.FILES)
        print("POST",request.POST)
        response={"flag":False}
        if username=="yuan" and password=="123":
            response["flag"]=True
        import json
        return HttpResponse(json.dumps(response))

      

  • 相关阅读:
    Codeforces Gym 100571A A. Cursed Query 离线
    codeforces Gym 100500 J. Bye Bye Russia
    codeforces Gym 100500H H. ICPC Quest 水题
    codeforces Gym 100500H A. Potion of Immortality 简单DP
    Codeforces Gym 100500F Problem F. Door Lock 二分
    codeforces Gym 100500C D.Hall of Fame 排序
    spring data jpa 创建方法名进行简单查询
    Spring集成JPA提示Not an managed type
    hibernate配置文件中的catalog属性
    SonarLint插件的安装与使用
  • 原文地址:https://www.cnblogs.com/liuwei0824/p/7827820.html
Copyright © 2011-2022 走看看