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))

      

  • 相关阅读:
    python 集合 set
    Meet Python
    Python 模块
    KNN
    Python Numpy包安装
    R分词
    Maximum Entropy Model(最大熵模型)初理解
    Conditional Random Fields (CRF) 初理解
    Naive Bayes (NB Model) 初识
    Hidden Markov Models(HMM) 初理解
  • 原文地址:https://www.cnblogs.com/liuwei0824/p/7827820.html
Copyright © 2011-2022 走看看