• Ajax基本知识


    Ajax工作原理

          Ajax技术核心是XMLHttpRequest对象(简称XHR对象),XHR为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器获得更多信息。意味着用户不必刷新页面也能取得新数据,然后通过DOM将数据插入到页面中。

       XHR对象:

           XMLHttpRequest  对象方法如下:

           about()   停止当前的请求。

           getAllResponseHeaders()   把HTTP请求的所有响应首部作为键/值对返回

           getResponseHeader("header")  返回指定首部的串值

           open("method","URL",[asyncFlag]) :

           建立对服务器的调用。method参数可以是GET、POST。url参数可以是相对URL或绝对URL。这个方法还包括可选的参数,是否异步(true或者false)。

          send(content) 向服务器发送请求。send接收一个参数,即作为请求主体发送的数据。如果不需要通过请求主体发送数据,则必须传入null,因为这个参数对有些浏览器来说是必须的。调用send()之后,请求就会分派到服务器。

    setRequestHeader("header", "value"): 把指定首部设置为所提供的值。在设置任何首部之前必须先调用open()。设置header并和请求一起发送 ('post'方法一定要 )

      XMLHttpRequest 对象属性描述:

          onreadystatechange:状态改变的事件触发器,每个状态改变时都会触发这个事件处理器.

          readyState:  请求的状态。

          有5个可取值:

          0: 未初始化。尚未调用open()方法。

          1:启动。已经调用open()方法,但尚未调用send()方法。

          2:发送。已经调用send()方法,但尚未接收到相应。

          3:接收。已经接收到部分相应数据。

          4:完成。已经接收到全部相应数据,而且已经可以在客户端使用了。

          responseText: 服务器的响应,返回数据的文本。

          responseXML:服务器的响应,返回数据的兼容DOM的XML文档对象 ,这个对象可以解析为一个DOM对象。

          status:服务器的HTTP状态码(如:404 = "文件末找到" 、200 ="成功" ,等等)

          statusText: 服务器返回的状态文本信息 ,HTTP状态码的相应文本(OK或Not Found(未找到)等等。

        XHR创建对象:

            所有现代浏览器(IE7,firefox,Opera,chrome和safari都支持原生的XMLHttpRequest对象)。

            创建XMLHttpRequest对象的语法如下:

             xhr = new XMLHttpRequest();

           老版本的浏览器IE7以下的使用ActiveX对象。

           xhr=new ActiveXObject("Microsoft.XMLHTTP");

         为此,综合以上,可以创建跨浏览器下的XHR对象,如下所示:

          function createXHR(){

                  var xhr;

                  if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari

                           xhr=new XMLHttpRequest();

                  }else{ // code for IE6, IE5

                           xhr=new ActiveXObject("Microsoft.XMLHTTP");

                  }

                  return xhr;

         }

        XMLHttpRequest对象用于和服务器交换数据实列如下:

       <script>

                  function createXHR(){

                           var xhr;

                           if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari

                                     xhr=new XMLHttpRequest();

                           }else{ // code for IE6, IE5

                                     xhr=new ActiveXObject("Microsoft.XMLHTTP");

                           }

                           return xhr;

                  }

                  var xhr = createXHR();

                  console.log(xhr.readyState);

                  xhr.onreadystatechange = function(){

                           console.log(xhr.readyState);

                           if(xhr.readyState == 4) {

                                     if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {

                                              console.log(xhr.responseText);

                                     }else {

                                              console.log("request was unsuccessful:"+xhr.status);

                                     }

                           }

                  };

                  //xhr.open('get','ajax.txt',false);

                  //xhr.send(null);

          </script>

         一:未调用open和send方法之前,xhr.readyState输出为0,也就是未初始化,未调用open方法。

         二:当把xhr.open方法打开时候,xhr.readyState输出为1,也就是启动了open方法,但尚未调用send()方法。

         三:当把xhr.send(null) 代码打开时候,xhr.readyState输出为4,说明接收到全部数据,且xhr.responseText输出为ajax.txt的内容了。

      请求中使用GET还是POST?

           与post相比,get更简单也更快,并且在大部分情况下可以使用,然后在以下情况下,请使用post请求:

               1. 无法使用缓存文件(更新服务器上的文件或者数据库)。

               2. 向服务器发送大量数据(POST没有数据量限制)。

               3. 发送包含未知字符的用户输入时,post比get更稳定也更可靠。

           还是上面的demo,把xhr.open第三个参数改为true,xhr.open('GET','ajax.txt',true); 可以看到打印出来分别为0,1,2,3,4。

           使用GET请求会有缓存,所以为了避免这种情况,需要在url后面增加唯一的id,比如可以加一个时间戳。

           GET请求存在安全性,也就是说安全性不高,且传输的数据有限制,所以要发送大量的数据如上所说,请使用POST请求。

        注意:使用GET请求经常会发生一个错误,就是查询字符串格式会有问题,查询字符串中每个参数的名称和值必须使用encodeURIComponent()进行编码,然后才能放到url的末尾,而且所有名-值对必须由和号(&)分隔,如下面所示:

            Xhr.open(“GET”,”ajax.txt?name1=value1&name2=value2”,true);

         不过我们可以使用下面的函数可以辅助现有的url的末尾添加查询字符串参数。

         function addURLParam(url,name,value) {

              url += (url.indexOf("?") == -1 ? "?" : "&");

              url += encodeURIComponent(name) + "=" + encodeURIComponent(value);

             return url;

          }

        Demo如下:

            <script>

                       function createXHR(){

                                var xhr;

                                if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari

                                         xhr=new XMLHttpRequest();

                                }else{ // code for IE6, IE5

                                         xhr=new ActiveXObject("Microsoft.XMLHTTP");

                                }

                                return xhr;

                       }

                       var xhr = createXHR();

                       console.log(xhr.readyState);

                       xhr.onreadystatechange = function(){

                                console.log(xhr.readyState);

                                if(xhr.readyState == 4) {

                                         if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {

                                                   console.log(xhr.responseText);

                                         }else {

                                                   console.log("request was unsuccessful:"+xhr.status);

                                         }

                                }

                       };

                       function addURLParam(url,name,value) {

                          url += (url.indexOf("?") == -1 ? "?" : "&");

                          url += encodeURIComponent(name) + "=" + encodeURIComponent(value);

                          return url;

                       }

     

                       var url = "ajax.txt";

                       url = addURLParam(url,"name","Nicholas");

                       xhr.open('get',url,false);

                       //xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");

                       //xhr.setRequestHeader("MyHeader","MyValue");

                       xhr.send(null);

              </script>

    如下所示:

          

         POST请求:

             一个简单的post请求如下:

            xhr.open('POST','ajax.txt',true);

            xhr.send(null);

            如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:如下所示:

            xhr.open('POST','ajax.txt',true);

            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");

            xhr.send("fname=Bill&lname=Gates");

             

    HTTP头部信息:

       每个http请求和相应都会带有相应的头部信息,其中有的对开发人员有用,有的没有什么用,XHR对象也提供了操作这两种头部(即请求头部和相应头部)信息的方法。

       默认情况下,在发送XHR请求的同时,还会发送下列头部信息。

    1. Accept: 浏览器能够处理的内容类型。
    2. Accept-Charset:浏览器能够显示的字符集。
    3. Accept-Encoding:浏览器能够处理的压缩编码。
    4. Accept-Language:浏览器当前设置的语言。
    5. Connection:浏览器与服务器之间连接的类型。
    6. Cookie: 当前页面设置的任何cookie。
    7. Host: 发出请求的页面所在的域。
    8. Referer:发出请求的页面的URL。
    9. User-Agent: 浏览器的用户代理的字符串。

    如上面的demo所示:

         

    跨域-----JSONP

          通过XHR实现ajax通信的一个主要限制,来源于跨域安全策略。默认情况下,XHR对象只能访问与包含它的页面同一个端口,同一个协议,同一个域名下的页面的资源文件,那么如果是不同域名下的文件资源是不允许访问,这是浏览器同源策略(为了安全性考虑)。那么如果开发中会需要在不同的域名下访问相对应的资源如何做呢?首先我们想到的是JSONP,那么什么是JSONP呢?

    我们可以先来看看jsonp.html页面代码如下:

    <!doctype html>

    <html lang="en">

        <head>

          <meta charset="UTF-8">

          <title>Document</title>

          <script src="jsonp.js"></script>

        </head>

     <body>

     </body>

    </html>

    其中jsonp.js内容为 alert("测试"); 打开页面可以看到弹出对话框 测试内容。这是在同域名下访问的,现在我让jsonp.js指向不同的域名,看能不能访问呢?首先在hosts文件下绑定

    127.0.0.1   a.test.com  然后把上面的jsonp.js改成 http://a.test.com/ajax/jsonp.js 接着在 页面上 访问 http://localhost/ajax/jsonp1.html 这个链接,也可以看出弹出”测试”文案对话框,由此可以知道:<script>标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行。

      什么是JSONP

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

      JSONP的作用?

         由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求。

      如何使用JSONP

      JSONP执行过程如下:

          首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 callback名字。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。如下demo:

    首先PHP代码如下:

     <?php   

    //服务端返回JSON数据   

    $arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);   

    $result=json_encode($arr);   

    //动态执行回调函数   

    $callback=$_GET['callback'];   

    echo $callback."($result)";  

    ?>

    会返回如下内容:Callback名称({"a":1,"b":2,"c":3,"d":4,"e":5});

    JS代码如下:

    <script type="text/javascript">   

                  function jsonpCallback(result) {   

                         //alert(result);   

                         for(var i in result) {   

                                console.log(i+":"+result[i]);//循环输出a:1,b:2,etc.   

                         }   

                  }   

                  var script = document.createElement("script");   

                  script.type = "text/javascript";   

                  script.src="http://a.test.com/ajax/jsonp.php?callback=jsonpCallback";   

                  document.getElementsByTagName("head")[0].appendChild(script);   

    </script>

    此时传给服务器的Callback名称为jsonpCallback,后台php返回的格式肯定是:jsonpCallback({"a":1,"b":2,"c":3,"d":4,"e":5}),所以在客户端jsonpCallback函数能正确的调用到。

    客户端JS代码在Jquery实现方式1如下:

    <script type="text/javascript">   

                       $.getJSON("http://a.test.com/ajax/jsonp.php?callback=?",function(result) {   

                                for(var i in result) {   

                                         alert(i+":"+result[i]);//循环输出a:1,b:2,etc.   

                                }   

                       });   

             </script>

    可以正确的输出。

    客户端JS代码在Jquery实现方式2如下:

    <script type="text/javascript">   

           $.ajax({   

                    url:"http://a.test.com/ajax/jsonp.php",   

                    dataType:'jsonp',   

                    data:'',   

                    jsonp:'callback',   

                   success:function(result) {   

                           for(var i in result) {   

                                 alert(i+":"+result[i]);//循环输出a:1,b:2,etc.   

                           }   

                  } 

             });    

      </script>  

        

    比如如下:

        

    我们还可以指定callback名称,如下:

      

  • 相关阅读:
    POJ3280Cheapest palindrome 经典dp
    hdu1257 最少拦截系统 LIS的应用
    代码着色 test
    Delphi 线程中的 Synchronize 和 临界区TCriticalSection 区别
    Delphi float浮点值转换整型int 方法
    Win.ini 介绍和配置结构
    Delphi Win API 打印函数 WriteProfileString
    Delphi ADOQuery 的Open和ExecSQL有什么区别
    SQL Server 中的 @、@@、#、## 、N 代表什么,以及SQL系统常用全局变量
    SQL 返回新增行的自增ID值方法
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/4023186.html
Copyright © 2020-2023  润新知