• 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")
              }
            }
          })
        });
    })
    

      

  • 相关阅读:
    Linux 常用命令大全
    冒犯了,问大家一个问题,会linux的进来帮我解决一下
    Linux 软件安装
    Ubuntu 12.04出现“device not managed”错误
    Linux 系统下vi编辑器的使用方法(copy其他人网站的,留着自己查用的)
    tar的打包压缩与解压缩,并解压到指定的目录
    Ubuntu文件的复制、移动和删除命令
    当Ubuntu12.04 如何获取root权限
    windows是用vnc远程连接ubuntu的方法
    Ubuntu 12.04 在root登陆之后没有声音的解决方法
  • 原文地址:https://www.cnblogs.com/zenghui-python/p/11073466.html
Copyright © 2020-2023  润新知