zoukankan      html  css  js  c++  java
  • AJAX

    AJAX准备的知识:JSON

    JSON指的是JavaScript对象表示法,也是轻量级的文本数据交换的格式

    并且独立于语言,具有自我描述性,更易理解。

    注意:JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。

    python与JS之间用json数据之间的转换:

    合格的JSON格式的对象:

    ["one", "two", "three"]
    { "one": 1, "two": 2, "three": 3 }
    {"names": ["张三", "李四"] }
    [ { "name": "张三"}, {"name": "李四"} ] 
    

      

    不合格的JSON格式的对象:

    { name: "张三", 'age': 32 }  ,{ "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;}  // 不能使用函数和日期对象
    }
    

     

    XML和JSON都使用结构化方法来标记数据,只不过JSON 格式有两个显著的优点:1.书写简单,一目了然;

    2.符合 JavaScript 原生语法,可以由解释引擎直接处理,不用另外添加解析代码。

    AJAX的介绍

    AJAXAsynchronous Javascript And XML)翻译成中文就是异步的JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

    AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

    AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程,即局部的刷新

    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

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

    AJAX的应用场景:

    我们前端往后端发请求的方式:
         1. 直接在地址栏输入URL
         2. a标签
         3. form表单
         4. AJAX

    HTTP请求的类型:
    GET
    POST

     AJAX特点:

     1. 异步
     2. 局部刷新(偷偷发请求)

    AJAX缺点:
     请求零碎,滥用对服务端压力大

     

    用jQuery封装的ajax方法:

    $("#b1").on("click", function () {
        // 点击 id是b1的按钮要做的事儿
          var i1 = $("#t1").val();
          var i2 = $("#t2").val();
          // 往后端发数据
          $.ajax({
              url: "/ajax_demo/",
              type: "get",
              data: {"t1": i1, "t2": i2},
              success: function (arg) {
                  {#alert(arg);#}
                  // 把返回的结果填充到 id是i3的input框中
                  $("#t3").val(arg);
              }
          })
      });
    

    $.ajax的参数

    data参数中的键值对,如果值值不为字符串,需要将其转换成字符串类型。用json将数据类型转变为字符串传递给后端。

    $("#b1").on("click", function () {
        $.ajax({
          url:"/ajax_add/",
          type:"GET",
          datatype:"json"    
          data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])},
          success:function (data) {
            $("#i3").val(data);
          }
        })
      })
    

    datatype: "josn",是帮你把数据封装为json格式的字符串,然后传递给视图函数;
    JsonResponse 多了一个请求头:'content_type'
    :视图函数返回的数据转为json字符串,只是在ajax接收函数返回的数据的时候自己帮你反序列为object对象了
    而 HttpResponse 也是将视图函数返回的数据转为json字符串,但是在ajax接收函数返回的数据的时候需要自己反序列化(json.parse)

    from django.http import JsonResponse 
                   user = auth.authenticate(username=username, password=pwd)
                if user:
                    # 用户名密码正确
                    # 给用户做登录
                    auth.login(request, user)
                    ret["msg"] = "/index/"
                else:
                    # 用户名密码错误
                    ret["status"] = 1
                    ret["msg"] = "用户名或密码错误!"
            else:
                ret["status"] = 1
                ret["msg"] = "验证码错误"
    
            return JsonResponse(ret)
    

    HTML中:

                $.ajax({
                    url: "/login/", // 进行二次验证
                    type: "post",
                    dataType: "json",
                    data: {
                        username: $('#inputName3').val(),
                        password: $('#inputPassword3').val(),
                        geetest_challenge: validate.geetest_challenge,
                        geetest_validate: validate.geetest_validate,
                        geetest_seccode: validate.geetest_seccode
                    },
                    success: function (data) {
                        if (data.status) {
                            $(".login-error").text(data.msg)
                        } else {
                            location.href = data.msg
                        }
                    }
                });
    

      

    AJAX请求如何设置csrf_token

    第一种是通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。 

    {% csrf_token %}
    
    
    <script>
    $.ajax({
      url: "/cookie_ajax/",
      type: "POST",
      data: {
        "username": "Q1mi",
        "password": 123456,
        "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val()  // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中
      },
      success: function (data) {
        console.log(data);
      }
    })
    </script>
    

    第二种是自己写插件,把通过获取返回的cookie中的字符串 放置在请求头中发送。

    只需要导入js即可以。

    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    var csrftoken = getCookie('csrftoken');
    
    function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    
    $.ajaxSetup({
      beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
      }
    });
    

      

    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对象
    
                 views.py:   json.loads(request.body.decode("utf8"))
            
    
    ######################------------traditional---------################
    
    traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]},
                  traditional为false会对数据进行深层次迭代;
    request.body是前端传过来的数据。
    如果是contentType:"application/json"的类型的,取数据要从request.body取。request.body=b'{"name":"a"}'。
    json.loads(request.body.decode("utf8"))

    如果是默认的processData,则request.body为b'name=a',默认的帮你把数据按照键值对的形式封装到request.POST里面。

    name = request.POST.get("name")
    
    
    

      

     

    AJAX上传文件

    和表单上传文件的意思差不多,对于表单来说,传文件需要添加这一属性

    enctype="multipart/form-data"
    

     

    而对于ajax来说的话:

    // 上传文件示例
    $("#b3").click(function () {
      var formData = new FormData();
      formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
      formData.append("f1", $("#f1")[0].files[0]);
      $.ajax({
        url: "/upload/",
        type: "POST",
        processData: false,  // 告诉jQuery不要去处理发送的数据
        contentType: false,  // 告诉jQuery不要去设置Content-Type请求头
        data: formData,
        success:function (data) {
          console.log(data)
        }
      })
    })
    

      

     

    补充:跨域请求

    同源策略与Jsonp

    同源策略:

    同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

    同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
    ==================================http://127.0.0.1:8001项目的index
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
    </head>
    <body>
    
    
    <button>ajax</button>
    {% csrf_token %}
    
    <script>
        $("button").click(function(){
    
    
            $.ajax({
                url:"http://127.0.0.1:7766/SendAjax/",
                type:"POST",
                data:{"username":"yuan","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},
                success:function(data){
                    alert(123);
                    alert(data)
                }
            })
        })
    </script>
    </body>
    </html>
    
    
    ==================================http://127.0.0.1:8001项目的views
    
    def index(request):
    
    
        return render(request,"index.html")
    
    
    def ajax(request):
        import json
        print(request.POST,"+++++++++++")
        return HttpResponse(json.dumps("hello"))
    

      

     上面的示例因为不满足同源的要求,则执行这个项目的时候会报错,

    已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:7766/SendAjax/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
    

    说明是浏览器对非同源请求返回的结果做了拦截。  

    jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。

    <script src="http://127.0.0.1:8008/books/?func=func_name"></script>
    

      这样的形式虽然能进行跨域,但是返回是一个变量,没有意义,做改进就是返回一个函数,把数据(必须是字符串,如果不是字符串的话就在前端报没有定义的错误)放入函数里面,通过调用函数能得到数据。

    def books(request):   #基于jsonp
    	funcname = request.GET.get("callbacks")
    	data = {"name":"alex","age":32}
    	return HttpResponse("%s('%s')"%(funcname,json.dumps(data)))
    <script>
        function alex(arg){
           console.log(arg)
        }
        </script>
    

     这样可以实现功能,但是不够灵活,因为代码一执行就进跨域了,因此才用伪造的ajax来实现跨域。

    模板中;

     $(".btn").on("click", function () {
            $.ajax({
                    url: "http://127.0.0.1:8008/books/",
                    type: "get",
                    dataType: "jsonp",    //伪造的ajax , 跨域请求,但是本质上还是基于script 上面的原理;
                    jsonp: "callbacks",   //k值 , v值(函数名)一般不写,是随机的生成的,即函数名不用自己取;
                    //jsonpCallback:"V值",
                    success: function (arg) {       //就相当于上面的函数,arg 就是跨域得到的数据。
                        var data = JSON.parse(arg);  //反序列化#}
                        console.log(typeof data);
                        console.log(data)
                    }
                }
            )
        })
    

    视图中:

    import json
    
    # def books(request):   #基于jsonp
    # 	funcname = request.GET.get("callbacks")
    # 	data = {"name":"alex","age":32}
    # 	return HttpResponse("%s('%s')"%(funcname,json.dumps(data)))
    

      

      

    从原因:CORS 头缺少 'Access-Control-Allow-Origin',可以看出还有一种跨域请求的。

    CORS

    CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

    整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

    因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

     

      //8000端口的   
    // 基于cors实现跨域请求 $.ajax({ url: "http://127.0.0.1:8008/books/", type: "get", success: function (arg) { console.log(arg) } }) ;

      

    def books(request):  # 基于cors实现跨域请求
    	data = {"name":"alex","age":32}
    	response = HttpResponse(json.dumps(data))
    	# response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8000"#(访问的地址)  #加到cors头上,即当时这个域名访问的时候就可以拿数据了
    	response["Access-Control-Allow-Origin"] = "*"  #所有的域名访问都可以
    	return response
    

      

    支持跨域,简单请求

    服务器设置响应头:Access-Control-Allow-Origin = '域名' 或 '*'

      

      

    补充一个SweetAlert插件示例

    $(".btn-danger").on("click", function () {
      swal({
        title: "你确定要删除吗?",
        text: "删除可就找不回来了哦!",
        type: "warning",
        showCancelButton: true,
        confirmButtonClass: "btn-danger",
        confirmButtonText: "删除",
        cancelButtonText: "取消",
        closeOnConfirm: false
        },
        function () {
          var deleteId = $(this).parent().parent().attr("data_id");
          $.ajax({
            url: "/delete_book/",
            type: "post",
            data: {"id": deleteId},
            success: function (data) {
              if (data.status === 1) {
                swal("删除成功!", "你可以准备跑路了!", "success");
              } else {
                swal("删除失败", "你可以再尝试一下!", "error")
              }
            }
          })
        });
    })
    

      

  • 相关阅读:
    饿了么P7级前端工程师进入大厂的面试经验
    前端程序员面试的坑,简历写上这一条信息会被虐死!
    这次来分享前端的九条bug吧
    移动端开发必会出现的问题和解决方案
    创建一个dynamics 365 CRM online plugin (八)
    创建一个dynamics 365 CRM online plugin (七)
    创建一个dynamics 365 CRM online plugin (六)
    创建一个dynamics 365 CRM online plugin (五)
    使用User Primary Email作为GUID的问题
    怎样Debug Dynamics 365 CRM Plugin
  • 原文地址:https://www.cnblogs.com/zenghui-python/p/11073466.html
Copyright © 2011-2022 走看看