zoukankan      html  css  js  c++  java
  • AJAX

    AJAX是什么?

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

    AJAX还有一个最大的特点就是,当服务器响应时,不用刷新整个浏览器页面,而是可以局部刷新。这一特点给用户的感受是在不知不觉中完成请求和响应过程。可总结为

    • 与服务器异步交互
    • 浏览器页面局部刷新

    那同步交互和异步交互的区别是什么?

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

    AJAX应用

    最常见的是我们在百度输入东西时,百度只是局部刷新了一下即可,还有就是在网页注册登陆时,用到的也是这个原理,下面举个简单的登陆注册页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <p>用户名<input type="text" name="username" onblur="func1(this)" onfocus="func2(this)">
        <span id="error"></span>
    </p>
    <p>密码<input type="password" name="password" onblur="func1(this)"><span id="pwd"></span></p>
    <input type="submit" value="submit">
    
    
    <script>
    
        function func1(self) {
            var username = self.value;
            var xmlhttp = creteXMLHttpRequest();
    
            xmlhttp.open("POST","/login/",true);
            xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    
            xmlhttp.send("username="+username);
    
            xmlhttp.onreadystatechange=function() {
                if (xmlhttp.readyState == 4 && xmlhttp.status==200){
                     var data = xmlhttp.responseText;
                     if (data=="1"){
                         document.getElementById("error").innerHTML="该用户已经存在";
                         document.getElementById("pwd").innerHTML="密码不符合朴准"
                     }
    
                }
            };
        }
    
        function func2(self) {
            document.getElementById("error").innerHTML=""
        }
    
        function creteXMLHttpRequest() {
            var xmlHttp;
            xmlHttp = new XMLHttpRequest();
            return xmlHttp
    
        }
    </script>
    
    
    </body>
    </html>
    login.html
    def login(req):
    
        if req.method == "POST":
    
            username = req.POST.get("username")
    
            if username == "flash":
                return HttpResponse('1')
    
            return HttpResponse('0')
    
        return render(req, "login.html")
    login

    AJAX的优缺点

    优点

    • AJAX使用JavaScript技术向服务器发送异步请求。
    • AJAX无需刷新整个页面。
    • 因为服务器响应内容不再是整个页面,而是页面的局部,所以AJAX的性能高。

    缺点

    • AJAX并不适合所有场景,很得时候还是要使用同步交互。
    • AJAX虽然提高了用户体验,但无形中向服务器发送的请求次数太多了,导致了服务器压力增大。
    • 因为AJAX是在浏览器中使用JavaScript技术完成的,所以还要处理浏览器的兼容问题。

    AJAX技术

    主要可以概括为四部操作

    • 创建核心对象;
    • 使用核心对象打开与服务器的连接;
    • 发送请求
    • 注册监听,监听服务器响应

    XMLHTTPRequest对象

    所有现代浏览器均支持XMLHTTPRequest对象(IE5和IE6使用 ActiveXObject)。

    XMLHTTPRequest用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

    • open(请求方式, URL, 是否异步)
    • send(请求体)
    • onreadystatechange,指定监听函数,它会在xmlHttp对象的状态发生变化时被调用

    内容信息

    • readyState,当前xmlHttp对象的状态,其中4状态表示服务器响应结束
    • status:服务器响应的状态码,只有服务器响应结束时才有这个东东,200表示响应成功;
    • responseText:获取服务器的响应体

    如果我们在创建对象时要考虑IE5和IE6的兼容性时,我们只需要,如果不需要,则不用写。

    function createXMLHttpRequest() {
            var xmlHttp;
            // 适用于大多数浏览器,以及IE7和IE更高版本
            try{
                xmlHttp = new XMLHttpRequest();
            } catch (e) {
                // 适用于IE6
                try {
                    xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    // 适用于IE5.5,以及IE更早版本
                    try{
                        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                    } catch (e){}
                }
            }            
            return xmlHttp;
        }
    

    AJAX-向服务器发送请求  

    我们可以使用XMLHttpRequest对象的open()方法和send()方法。

    open(method,url,async):规定请求类型,URL以及是否异步处理请求

    • menthod:请求的类型:GET或POST
    • url:文件在服务器上的位置
    • async: true(异步)或 flash(同步)。默认为true

    send(string):将请求发送服务器请求

    • string:仅用于POST

    当在下面情况下时,要使用POST请求

    • 无法使用缓存文件(更新服务器上的文件或数据库)
    • 向服务器发送大量数据(POST没有数据量限制)
    • 发送包含未知字符用户输入时,POST比GET更稳定也更可靠

    当我们使用POST请求时,需要注意的是在open和send之间添加如下信息即可

    xmlhttp.open("POST","ajax_test.asp",true);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.send("fname=Bill&lname=Gates");
    

    服务器响应  

    XMLHttpRequest对象有一个onreadystatechange事件,它会在XMLHttpRequest对象的状态发生变化时被调用。下面介绍一下XMLHttpRequest对象的5种状态:

    • 0:初始化未完成状态,只是创建了XMLHttpRequest对象,还未调用open()方法;
    • 1:请求已开始,open()方法已调用,但还没调用send()方法;
    • 2:请求发送完成状态,send()方法已调用;
    • 3:开始读取服务器响应;
    • 4:读取服务器响应结束。 

    onreadystatechange事件会在状态为1234时引发。但通常我们只关心最后一种状态,即读取服务器响应结束时,客户端才会做出改变。我们可以通过XMLHttpRequest对象的readyState属性来得到XMLHttpRequest对象的状态。

    xmlHttp.onreadystatechange = function() {
                if(xmlHttp.readyState == 4) {
                    alert('hello');    
                }
            };
    

    我们还需要考虑服务器响应的状态码是否为200等,可以用status获取状态妈如下

    xmlHttp.onreadystatechange = function() {
                if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    alert(xmlHttp.responseText);    
                }
            };
    

    我们注意到了在获得来自服务器的响应时,可以使用responseText或responseXML属性来获取

    • responseText:获取字符串的响应数据
    • responseXML:获取XML形式的响应数据

    jQuery实现AJAX

    我们可以使用两个快捷方法去使用

    $.get(url, [data], [callback], [type])
    $.post(url, [data], [callback], [type])
    

    下面以简单实例去看看如何显示。

    def J_T(req):
    
        # print(req.GET) # 打印GET请求的数据
        # print(req.POST)  # 打印POST请求数据
    
        #dic = {"name": "aa"}
    
       # return HttpResponse(json.dumps(dic))
        return HttpResponse("OK")
    <button id="b" onclick="func1()">点击</button>
    <script>
        function func1() {
            test()
        }
        function test() {
          $.get('/J_T/');
          $.post('/J_T/')
        
    
      }
    
    </script>
    GET/POST
    <script>
        function func1() {
            test()
        }
        function test() {
             $.get('/J_T/', function (data, callbacktype, jqXHR) {
             console.log(data); // OK
           console.log(callbacktype);//success
              console.log(jqXHR);  //object
       })
    }
    
    
    </script>
    callback回调函数
    <script>
        function func1() {
            test()
        }
        function test() {
              $.get('/J_T/?a=12&b=4')
              $.get('/J_T/',{a:12,b:4})
             $.post('/J_T/',{name:'aaa'})
    
    }
    </script>
    传data

    $.getScript()

    $.getScript()使用 AJAX 请求,获取和运行 JavaScript:

    function testGetScript() {
            // alert(testFun(3, 4));
            $.getScript('test.js', function () {
                alert(add(1, 6));
            });
        }
    
    // test.js
    function add(a,b){
       return a+b
       }
    

    $.ajax的两种使用方式

    function basicUsage() {
          //第一种
            $.ajax('/test', {
                success: function () {
                    alert('ok');
                }
            });
        
         //第二种
            $.ajax({
                url: '/test',
                success: function () {
                    alert('okk');
                }
            });
        }    
    

    需要注意的事,success函数,在程序成功的时候会执行它,还有几种如下 success、error、statusCode、complete:

    • success:程序执行成功时促发的函数
    • error:程序执行失败时促发的函数
    • complete:不管程序成不成功都会促发的函数
    • statusCode:根据获取的状态码去对应的促发函数
    function callbacksUsage() {
            $.ajax('/user/allusers', {
    
                success: function (data) {
                    console.log(arguments);
                    console.log("aa")
                },
    
                error: function (jqXHR, textStatus, err) {
    
                    // jqXHR: jQuery增强的xhr
                    // textStatus: 请求完成状态
                    // err: 底层通过throw抛出的异常对象,类型与值与错误类型有关
                    console.log(arguments);
                },
    
                complete: function (jqXHR, textStatus) {
                    // jqXHR: jQuery增强的xhr
                    // textStatus: 请求完成状态 success | error
                    console.log('statusCode: %d, statusText: %s', jqXHR.status, jqXHR.statusText);
                    console.log('textStatus: %s', textStatus);
                },
    
                statusCode: {
                    '403': function (jqXHR, textStatus, err) {
                        console.log(arguments);
                        console.log('status code 403');
                        console.log("ahha403")
                    },
                    '400': function () {
                        console.log('status code 400');
                        console.log("hhhh400")
                    }
                }
            });
        }
    示例

    在向服务器请求时的数据可分为4种: data, processData, contentType, traditional

    • data:当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式(urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。
    • processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if 为false,那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString(),最后得到一个[object,Object]形式的结果。一般情况下不做处理。
    • contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。用来指明当前请求的数据编码格式;urlencoded: ?a=1&b=2;如果想以其他方式提交数据,比如contentType:"application/json",即向服务器发送一个json字符串:
    • traditional:一般是我们的data数据有数组时会用到

    具体示例如下

    function testData() {
           $.ajax("/test",{////此时的data是一个json形式的对象
              data:{
                a:1,
                b:2
              }      
           });
    
    //显示结果  ?a=1&b=2
    data
    $.ajax({
              url:'/test/',
              type:"POST",
             data:{a:1,b:2},
              processData:false, //默认为true,改成false后不需要转码直接发送,不常用
            })
    processData
    $.ajax("/test",{
               
              data:JSON.stringify({
                   a:22,
                   b:33
               }),
               contentType:"application/json",
               type:"POST",
               
           });
    
    //{a: 22, b: 33}
    contentType

    这里需要特别注意的是:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象

    $.ajax({
            url:'/test/',
            type:"POST",
            data:{a:1,b:[3,4]}, //没加traditional之前{'b[]': ['3', '4'], 'a': ['1']}
            traditional:true  //加traditional之后 {'a': ['1'], 'b': ['3', '4']}
            })
            
    traditional

    响应数据分为dataType、dataFilter:

     dataType:预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用data Type。比如服务器响应(Response Headers)的content Type是json格式(json对象),但是我们希望得到的是一个json字符串,那就可以把dataType:text,这样ajax方法就不会把返回的数据进行json格式的转换。

    可用值:html|xml|json|text|script

    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=['aa','little aa']
    
        #return HttpResponse(l)
        return HttpResponse(json.dumps(l))
    
    //---------------------------------------------------
        function testData() {
    
            $.ajax('ajax_get', {
               success: function (data) {
               console.log(typeof(data));
                                         },
               dataType:"json",
                                }
                           )}
    
    注解:Response Headers的content Type为text/html,所以返回的是String;但如果我们想要一个json对象
        设定dataType:"json"即可,相当于告诉ajax方法把服务器返回的数据转成json对象发送到前端.结果为objec
    示例

    dataFilter:Function 给 Ajax返回的原始数据的进行预处理的函数

    function testData() {
    
             $.ajax('ajax_get', {
               success: function (data) {
                   console.log(data);
                },
    
    
                dataType: 'json',
                dataFilter: function(data, type) {
                    console.log(data);//["aa", "little aa"]
                    console.log(type);//json
                    //var tmp =  JSON.parse(data);
                    return tmp.length;//2
                }
            });}
    示例

    前置处理 beforeSend(XHR)

    类型:Function 发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。XMLHttpRequest 对象是唯一的参数。这是一个 Ajax 事件。如果返回 false 可以取消本次 ajax 请求。

    function testData() {
            $.ajax('ajax_get', {
             beforeSend: function (jqXHR, settings) {
                    console.log(arguments);
                    console.log('beforeSend');
                    jqXHR.setRequestHeader('test', 'haha');
                    jqXHR.testData = {a: 1, b: 2};
                },
                success: function (data) {
                    console.log(data);
                },
    
                complete: function (xhr) {
                    console.log(xhr);
                    console.log(xhr.testData);
                },
    
            })};
    示例

    jsonp

    类型:String

    在一个 jsonp 请求中重写回调函数的名字。这个值用来替代在 "callback=?" 这种 GET 或 POST 请求中 URL 参数里的 "callback" 部分,比如 {jsonp:'onJsonPLoad'} 会导致将 "onJsonPLoad=?" 传给服务器。

    jsonpCallback

    类型:String

    为 jsonp 请求指定一个回调函数名。这个值将用来取代 jQuery 自动生成的随机函数名。这主要用来让 jQuery 生成度独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存 GET 请求的时候,指定这个回调函数名。

    JSON

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。

    JSON是用字符串来表示Javascript对象,例如可以在django中发送一个JSON格式的字符串给客户端JavascriptJavascript可以执行这个字符串,得到一个Javascript对象。json就是js对象的一种表现形式(字符串的形式)

    JSON语法(使用双引号包含数据 "...")

    • 数据在名称/值对中
    • 数据由逗号分隔
    • 花括号保存对象(对象需要使用大括号括起来)
    • 方括号保存数组(数组使用中括号括起来)

    JSON值

    • 数字  (整数或浮点数)
    • 字符串(在双引号中)
    • 逻辑值(true 或 false
    • 数组   (在方括号中)
    • 对象   (在花括号中)
    • null

     .parse()和.stringify() 

    • .parse()是从一个字符串中解析出json对象
    • .stringify()是从一个对象中解析出字符串
    var str = '{"name":"aa","age":"23"}'
    
    结果:
    JSON.parse(str)
    
    str["name"]:  aa
    str["age"]: 23
    
    var a = {a:1,b:2}
    
    结果:
    
    JSON.stringify(a)
    
    "{"a":1,"b":2}"
    

    跨域请求 

    在执行跨域请求时,对方需给我们提供一个接口,否则无法完成

    首先了解什么是同源策略?

    览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。

    jsonp的js实现

    JSONP是JSON with Padding的略称。可以让网页从别的域名(网站)那获取资料,即跨域读取数据。

    它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

     #---------------------------http://127.0.0.1:8001/login
    
     def login(request):
        print('hello ajax')
        return render(request,'index.html')
    
    
     #---------------------------返回用户的index.html
    
     <h1>发送JSONP数据</h1>
    
    <script>
        function fun1(arg){
            alert("hello"+arg)
        }
    </script>
    <script src="http://127.0.0.1:8002/get_byjsonp/"></script>
    
    
    #-----------------------------http://127.0.0.1:8002/get_byjsonp
    
    def get_byjsonp(req):
        print('8002...')
        return HttpResponse('fun1("aaa")')
    View Code

    动态的去创建script标签

    <script>
        function addScriptTag(src){
         var script = document.createElement('script');  //空标签
             script.setAttribute("type","text/javascript");
             script.src = src;
             document.body.appendChild(script);  //添加到body内
        }
        function fun1(arg){
            alert("hello"+arg)
        }
    
        window.onload=function(){
            addScriptTag("http://127.0.0.1:8002/get_byjsonp/")
        }
    </script>
    创建script标签

    将自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调

    <script>
        function addScriptTag(src){
         var script = document.createElement('script');
             script.setAttribute("type","text/javascript");
             script.src = src;
             document.body.appendChild(script);
        }
        function fetch(arg){
            alert("hello"+arg)
        }
    
        window.onload=function(){
            addScriptTag("http://127.0.0.1:8002/get_byjsonp?callback=fetch")
        }
        
    </script>
    
    #--------------------------------http://127.0.0.1:8002/get_byjsonp    
        def get_byjsonp(req):
    
        callback=req.GET.get('callback')
        print(callback)
        return HttpResponse('%s("aa")'%callback)
    动态去取函数去执行

    jQuery对JSONP的实现

    jQuery使用时的方法为$.getJSON(url,[data],[callback])

    <script type="text/javascript">
        $.getJSON("http://127.0.0.1:8002/get_byjsonp?callback=?",function(arg){
            alert("hello"+arg)
        });
    </script>
    
    <script type="text/javascript" src="/static/jquery-2.2.3.js"></script>
    
    <script type="text/javascript">
       $.ajax({
            url:"http://127.0.0.1:8002/get_byjsonp",
            dataType:"jsonp",
            jsonp: 'callbacks',
            jsonpCallback:"fetch"
       });
        function fetch(arg){
            alert(arg);
        }
    </script>
     
    #--------------------------------- http://127.0.0.1:8002/get_byjsonp
     def get_byjsonp(req):
    
        callback=req.GET.get('callbacks')
        print(callback)
        return HttpResponse('%s("yuan")'%callback)
    示例

    我们也可不用去自己定义

    <script type="text/javascript" src="/static/jquery-2.2.3.js"></script>
    
    <script type="text/javascript">
       $.ajax({
            url:"http://127.0.0.1:8002/get_byjsonp",
            dataType:"jsonp",
            jsonp: 'callbacks',
            success:function(data){
                alert(data)
            }
       });
    
    </script>
     #-------------------------------------http://127.0.0.1:8002/get_byjsonp
    def get_byjsonp(req):
    
        callback=req.GET.get('callbacks')
        print(callback) #jQuery223015502220591490135_1477560648881
    return HttpResponse("%s('aa')"%callback)
    示例

    需要注意的是:jsonpCallback:"fetch";如果不加这个参数,则自动生成一个随机名字。

    下面我们利用跨域请求去请求一个电视台的列表信息

    def index(req):
    
        return render(req, "index.html")
    index函数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <button onclick="func1()">AJAX提交</button>
    
    <script src="/static/jquery-3.1.1.js"></script>
    
    <script>
        function func1() {
            $.ajax({
                url:"http://www.jxntv.cn/data/jmd-jxtv2.html",
                type:"GET",
                dataType:"jsonp",
            })
        }
    
        //这里lsit函数被后台定死了,所以在$.ajax内部也就不用写jsonp: 'callbacks'和jsonpCallback:"fetch"了
        function list(e) {
            var obj=e['data'];
            $.each(obj,function () {  //循环遍历,相当于for循环
                console.log($(this));
                var weekend=$(this)[0]["week"];
                $("body").append("<p>"+weekend+"</p>");
    
                var show_list=$(this)[0]["list"];
                $.each(show_list,function () {
                    var name=$(this)[0]["name"];
                    var link=$(this)[0]["link"];
                    $("body").append("<p><a href='"  +link  +    "'>" + name+"</a></p>")
                })
    
            })
    
        }
    
    </script>
    
    </body>
    
    </html>
    index.html

      

      

     

  • 相关阅读:
    毕业设计——第三章 开发方法及系统实现(2)
    毕业设计——第三章 开发方法及系统实现(5)
    毕业设计——第二章 系统总体设计(2)
    Blue Screen Of Death ( BSOD ) 错误信息解析解释
    毕业设计——第三章 开发方法及系统实现(3)
    毕业设计——第三章 开发方法及系统实现(4)
    dvbbs7.1sp1最新漏洞的研究和利用
    毕业设计——第二章 系统总体设计(1)
    一则笑话
    线性代数
  • 原文地址:https://www.cnblogs.com/flash55/p/6123196.html
Copyright © 2011-2022 走看看