Ajax詳解


Ajax

Ajax 是什么

  1. Asynchronous [e'sɪŋkrənəs] Javascript And XML, AJAX 不是一門的新的語言,而是對現有技術的綜合利用。 本質是在HTTP協議的基礎上以異步的方式與服務器進行通信。
  2. 異步 : 某段程序執行時不會阻塞其他程序的執行, 表現形式是程序的執行順序不依賴程序本身的書寫順序, 相反的情況依次執行, 那就是同步核心在於不會阻塞程序的執行, 從而提升整體執行效率

原生 Ajax 的使用

XMLHttpRequest

  • XMLHttpRequest 是瀏覽器的內置對象, 作用是在后台與服務器通信( 交換數據 )
  • 用於網頁的局部更新, 而不是刷新整個頁面
    // 創建一個新的 XMLHttpRequest 對象
    var xhr = new XMLHttpRequest();

請求 Request

HTTP 請求由 3 個部分組成, 正好和 XMLHttpRequest 相對應

  1. 請求行 open
        xhr.open( 'post', '01.php' );
    
  2. 請求頭 setRequestHeader
        // post 請求需要設置頭
        xhr.setRequestHeader( 'Conent-Type' , 'application/x-www-form-urlencoed' );
        // get 請求可以不設置請求頭
    
  3. 請求主體 send
        xhr.send( 'name=Jim&age=18' );
        // get 可以傳空, 因為在頭的時候已經傳過數據了
    

響應 Response

  1. HTTP 響應是由服務端放出的, 客戶端更應該關心度額是響應的結果
  2. HTTP 響應由 3 個部分組成, 與 XMLHttpRequest 的方法或屬性成對應關系
  3. 由於服務器做出響應需要時間( 網絡延遲等原因 ),所以需要監聽服務器響應狀態, 再進行處理
    if( xhr.readyState == 4 && xhr.status == 200 ){
        // 進行下一步操作, 如渲染頁面
        document.querySelector( '#result' ).innerHTML = xhr.responseText;
    }

步驟分析

  1. 請求未初始化 ( 還沒有調用 open() )
  2. 請求已經建立, 但是還沒有發送 ( 還沒有調用send() )
  3. 請求已發送, 正在處理中 ( 通常現在可以從相應中獲取內容頭 )
  4. 請求在才處理中 , 通常響應中已經有部分數據可以用了, 但是服務器還沒有完全完成響應
  5. 響應已經完成, 可以獲取並使用服務器的響應了

其他注意點

  1. 可以使用 onreadystatechange 來監聽 XMLHttpRequest 的狀態
  2. 獲取行狀態 ( 包括行狀態碼和狀態信息 )
    xhr.status  // 狀態碼
    xhr.statusText // 狀態碼嘻嘻
  1. 獲取響應頭
    xhr.getResponseHeader( 'Content-Type' );
    xhr.getAllResponseHeaders();
  1. 獲取響應主體
    xhr.responseText    // json, 文本 類型
    xhr.responseXML     // xml 類型

API 詳解

  1. xhr.open() 發送請求, 可以是 get 或者 post 方式
  2. xhr.setRequestHeader() 設置請求頭
  3. xhr.send() 發送請求主體, 如果是 get 方式使用 xhr.send(null), 因為在 open 中已經發送了請求主體
  4. xhr.onreadystatechange = functtion(){} 監聽響應狀態
  5. xhr.status 表示響應碼, 如 200 表示成功
  6. xhr.statusText 表示響應信息. 如 ok
  7. xhr.getAllResponseHeaders() 獲取全部響應頭信息
  8. xhr.getResponseHeader( 'key' ) 獲取指定響應頭信息
  9. xhr.reponseText xhr.responseXML 都表示響應主體, 格式不同

get 和 post 的差異

  1. get 沒有請求主體, 使用 xhr.send(null) 發送請求主體
  2. get 可以通過請求 url 上添加請求函數
  3. post 可以通過 xhr.send( 'name=itcast&age=10' ) 發送請求主體
  4. post 需要設置
  5. get 性能高( 基本上獲取內容都是使用get )
  6. get 大小限制約 4kb, post 則沒有限制

get 方式的 請求響應

    var xhr = new XMLHttpRequest;
        xhr.open('get','01.php');
        xhr.send(null);
        xhr.onreadystatechange = function(){
         if(xhr.status == 200 && xhr.readyState == 4){
             /*獲取到XML格式內容  放回的是DOM對象  document*/
             var xml = xhr.responseXML;
             /*通過選着器可以獲取到xml的數據*/
             console.log(xml.querySelectorAll('array')[0].querySelector('src').innerHTML);
         }
    }

post 請求和響應

    //初始化
    var xhr = new XMLHttpRequest();
    //請求行
    xhr.open("post","03 AjaxPost.php");
    //請求頭
    xhr.setRequestHeader("content-type","application/x-www-form-urlencoded")
    //請求內容
    xhr.send("username=rxt&password=1234");

    //監聽響應改變
    xhr.onreadystatechange = function(){

        /*什么時候才算是http通訊結束 在readyState=4的是 響應完成*/
        /*什么是才算是通訊成  status 200 */

        if(xhr.status ==200 && xhr.readyState == 4){
            document.querySelector("div").innerHTML = xhr.responseText;
        }

    }

XML

  1. XML 是可擴展標記語言(Extensible Markup Language)的縮寫,其中的 標記(markup)是關鍵部分。XML 可以創建內容,然后使用限定標記標記它,從而使每個單詞、短語或塊成為可識別、可分類的信息。您創建的文件,或文檔實例 由元素(標記)和內容構成。

  2. 特點

    • 必須要有根元素
    • 不能以空格, 數字或者 . 開頭, 對大小寫敏感
    • 不能交叉嵌套
    • 屬性雙引號
    • 特殊符號要使用屍體
    • 注釋和 HTML 一樣
  3. XML 雖然可以描述傳輸復雜數據, 但是其解析過於復雜並且體積較大, 所以實際開發使用較少

  4. 格式

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
    <arrayList>
        <array>
            <src>images/banner.jpg</src>
            <newPirce>12.00</newPirce>
            <oldPrice>30.00</oldPrice>
        </array>
        <array>
            <src>images/banner.jpg</src>
            <newPirce>12.00</newPirce>
            <oldPrice>30.00</oldPrice>
        </array>
    </arrayList>
    </root>

JSON

JavaScript Object Notation,另一種輕量級的文本數據交換格式,獨立於語言。

特點

1. 數據在鍵值對中
2. 數據由 " , " 分隔, 最后一個鍵值不能帶 " , "
3. " [] "保存數組, " {} " 保存對象
4. 使用 "" 雙引號包裹鍵值
    [
        {"src":"images/detail01.jpg","oldPrice":"10.12","newPrice":"130.00"},
        {"src":"images/detail02.jpg","oldPrice":"1.00","newPrice":"11.00"},
        {"src":"images/detail03.jpg","oldPrice":"100.00","newPrice":"1000.00"}
    ]

不同語言下的解析 JSON

JSON數據在不同語言進行傳輸時,類型為字符串,不同的語言各自也都對應有解析方法,需要解析完成后才能讀取

  1. php 方法
  • json_encode() : 將 php 數組轉化為 json 字符
  • json_decode() : 將 json 字符串 轉換為 php 數組
    <?php
        header('Content-Type:text/html;charset=utf-8');
        /*以json格式傳輸數據的時候要求響應內容格式是   application/json*/
        /*注意也可以不設置  但是這遵循的一個規范*/

        /*file_get_contents 獲取文件內容*/
        $json = file_get_contents('01.json');

        /*輸出json內容*/
        echo $json;
        echo '<br><br>';

        $array = array(
            array('src'=>'images/detail01.jpg','newPrice'=>'12.00','oldPrice'=>'455.00'),
            array('src'=>'images/detail02.jpg','newPrice'=>'65.00','oldPrice'=>'878.00'),
            array( 'src'=>'images/detail01.jpg','newPrice'=>'100.00','oldPrice'=>'1000.00')
        );

        /*將php數組轉化成json字符*/
        $json_array = json_encode($array);
        echo $json_array;
        echo '<br><br>';

        /*將json字符轉化成php數組*/
        $array_json = json_decode($json_array);
        echo $array_json;
        echo '<br><br>';
    ?>

javascript 解析方法

  • JSON對象
    • JSON.parse() : 字符串 轉 JSON 對象
    • JSON.stringify() : JSON 對象 轉 字符串
  • JSON 兼容處理 : json2.js
    var xhr = new XMLHttpRequest;
    xhr.open('get','01.php');
    xhr.send(null);
    xhr.onreadystatechange = function(){
       if(xhr.status == 200 && xhr.readyState == 4){
           /*獲取僅僅是字符串*/
           var text = xhr.responseText;

           /*需要把字符串轉化成JSON對象*/
           var json_obj = JSON.parse(text);
           console.log(json_obj);

           /*我們也可以把JSON對象轉化成字符串*/
           var json_str = JSON.stringify(json_obj);
           console.log(json_str);
       }
    }

封裝 Ajax 工具函數

    /*
    * 1. 請求的類型                type    get post
    * 2. 請求地址                  url
    * 3. 是異步的還是同步的         async   false true
    * 4. 請求內容的格式            contentType
    * 5. 傳輸的數據                data    json對象
    *
    * 6.響應成功處理函數           success   function
    * 7.響應失敗的處理函數         error     function
    *
    * 這些都是動態參數  參數對象  options
    * */

    /*封裝一個函數*/
    window.$ = {};
    /*申明一個ajax的方法*/
    $.ajax = function(options){

    if(!options || typeof options != 'object'){
        return false;
    }

    /*請求的類型*/
    var type = options.type || 'get';/*默認get*/
    /*請求地址 */
    var url = options.url || location.pathname;/*當前的地址*/
    /*是異步的還是同步的 */
    var async = (options.async === false)?false:true;/*默認異步*/
    /*請求內容的格式 */
    var contentType = options.contentType || "text/html";

    /*傳輸的數據 */
    var data = options.data || {};/*{name:'',age:''}*/
    /*在提交的時候需要轉成 name=xjj 這種格式*/

    var dataStr = ''/*數據字符串*/

    for(var key in data){
        dataStr += key+'='+data[key]+'&';
    }

    dataStr = dataStr && dataStr.slice(0,-1);

    /*ajax 編程*/
    var xhr = new XMLHttpRequest();

    /*請求行*/
    /*(type=='get'?url+'?'+dataStr:url)判斷當前的請求類型*/
    xhr.open(type,(type=='get'?url+'?'+dataStr:url),async);

    /*請求頭*/
    if(type == 'post'){
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    }

    /*請求主體*/
    /*需要判斷請求類型*/
    xhr.send(type=='get'?null:dataStr);

    /*監聽響應狀態的改變  響應狀態*/
    xhr.onreadystatechange = function(){
        /*請求響應完成並且成功*/
        if(xhr.readyState == 4 && xhr.status == 200){
            /*success*/
            var data = '';
            var contentType = xhr.getResponseHeader('Content-Type');
            /*如果我們服務器返回的是xml*/
            if(contentType.indexOf('xml') > -1){
                data = xhr.responseXML;
            }
            /*如果我們的服務器返回的是json字符串*/
            else if(contentType.indexOf('json') > -1){
                /*轉化json對象*/
                data = JSON.parse(xhr.responseText);
            }
            /*否則的話他就是字符串*/
            else{
                data = xhr.responseText;
            }

            /*回調 成功處理函數*/

            options.success && options.success(data);
        }
        /*計時請求xhr.status不成功  他也需要的響應完成才認作是一個錯誤的請求*/
        else if(xhr.readyState == 4){
            /*error*/
            options.error && options.error('you request fail !');

        }

    }
    }
    $.post = function(options){
    options.type = 'post';
    $.ajax(options);
    }
    $.get = function(options){
    options.type = 'get';
    $.ajax(options);
    }

jQuery 中的 Ajax

  • jQuery為我們提供了更強大的Ajax封裝
  • $.ajax({}) 可配置方式發起Ajax請求
  • $.get() 以GET方式發起Ajax請求
  • $.post() 以POST方式發起Ajax請求
  • $('form').serialize() 序列化表單(即格式化key=val&key=val)
  • url 接口地址
  • type 請求方式
  • timeout 請求超時
  • dataType 服務器返回格式
  • data 發送請求數據
  • beforeSend: function () {} 請求發起前調用
  • success 成功響應后調用
  • error 錯誤響應時調用
  • complete 響應完成時調用(包括成功和失敗)
  • jQuery Ajax介紹
  • http://www.w3school.com.cn/jquery/jquery_ref_ajax.asp

jQuery 中 Ajax 的使用

$.ajax({
    type : 'get',
    url : 'getCode.php',
    data : {'mobile' : phone},
    dataType : 'json',
    beforeSend : function(){

    },
    success : function(info){

    }
});

模板引擎

artTemplate 簡潔語法模板

    // 簡潔語法
    {{if admin}}
        {{include 'admin_content'}}

        {{each list}}
            <div>{{$index}}. {{$value.user}}</div>
        {{/each}}
    {{/if}}

    // 編寫模板
    <script id="test" type="text/html">
        <h1>{{title}}</h1>
        <ul>
            {{each list as value i}}
                <li>索引 {{i + 1}} :{{value}}</li>
            {{/each}}
        </ul>
    </script>
    // 渲染數據
    var data = {
        title: '標簽',
        list: ['文藝', '博客', '攝影', '電影', '民謠', '旅行', '吉他']
    };
    var html = template('test', data);
    document.getElementById('content').innerHTML = html;

artTemplate js 原生語法模板

    // 模板 js 原生語法
    <h1><%=title%></h1>
    <ul>
    <%for(i = 0; i < list.length; i ++) {%>
        <li>條目內容 <%=i + 1%> :<%=list[i]%></li>
    <%}%>
    </ul>
    <% 與 %> 符號包裹起來的語句則為模板的邏輯表達式。
    對內容編碼輸出:<%=content%>
    不編碼輸出:<%=#content%>

同源跨域

  1. 同源
    2. 同源策略是瀏覽器的一種安全策略,所謂同源是指,域名,協議,端口完全相同。

  2. 跨域
    3. http://api.example.com/detail.html 不同源 域名不同
    4. https//www.example.com/detail.html 不同源 協議不同
    5. http://www.example.com:8080/detail.html 不同源 端口不同
    6. http://api.example.com:8080/detail.html 不同源 域名、端口不同
    7. https://api.example.com/detail.html 不同源 協議、域名不同
    8. https://www.example.com:8080/detail.html 不同源 端口、協議不同
    9. http://www.example.com/detail/index.html 同源 只是目錄不同

  3. 跨域方案

    1. 頂級域名相同的可以通過domain.name來解決,即同時設置 domain.name = 頂級域名(如example.com)
    2. document.domain + iframe
    3. window.name + iframe
    4. location.hash + iframe
    5. window.postMessage()
  4. jsonp
    5. json with padding
    6. 原理
    7. 其本質是利用了標簽具有可跨域的特性, 由服務端返回一個預先定義好的Javascript函數的調用,並且將服務器數據以該函數參數的形式傳遞過來, 此方法需要前后端配合完成。

        <!--
        當我們用script標簽去加載的時候  會把內容解析成js去執行
        -->
        <script>
            function fuc(data){
                console.log(data.name);
            }
        </script>
        <script src="http://www.guangzhou.com/api.php?callback=fuc"></script>
    
    

jQuery 中的 Ajax

  1. url: 要求為String類型的參數,(默認為當前頁地址)發送請求的地址。
  2. type: 要求為String類型的參數,請求方式(post或get)默認為get。注意其他http請求方法,例如put和delete也可以使用,但僅部分瀏覽器支持。
  3. timeout: 要求為Number類型的參數,設置請求超時時間(毫秒)。此設置將覆蓋$.ajaxSetup()方法的全局設置。
  4. async:要求為Boolean類型的參數,默認設置為true,所有請求均為異步請求。如果需要發送同步請求,請將此選項設置為false。注意,同步請求將鎖住瀏覽器,用戶其他操作必須等待請求完成才可以執行。
  5. cache:要求為Boolean類型的參數,默認為true(當dataType為script時,默認為false)。設置為false將不會從瀏覽器緩存中加載請求信息。
  6. data: 要求為Object或String類型的參數,發送到服務器的數據。如果已經不是字符串,將自動轉換為字符串格式。get請求中將附加在url后。防止這種自動轉換,可以查看processData選項。對象必須為key/value格式,例如{foo1:"bar1",foo2:"bar2"}轉換為&foo1=bar1&foo2=bar2。如果是數組,JQuery將自動為不同值對應同一個名稱。例如{foo:["bar1","bar2"]}轉換為&foo=bar1&foo=bar2。
  7. dataType: 要求為String類型的參數,預期服務器返回的數據類型。如果不指定,JQuery將自動根據http包mime信息返回responseXML或responseText,並作為回調函數參數傳遞。
    • 可用的類型如下:
      • xml:返回XML文檔,可用JQuery處理。
      • html:返回純文本HTML信息;包含的script標簽會在插入DOM時執行。
      • script:返回純文本JavaScript代碼。不會自動緩存結果。除非設置了cache參數。注意在遠程請求時(不在同一個域下),所有post請求都將轉為get請求。
      • json:返回JSON數據。
      • jsonp:JSONP格式。使用SONP形式調用函數時,例如myurl?callback=?,JQuery將自動替換后一個“?”為正確的函數名,以執行回調函數。
      • text:返回純文本字符串。
  8. beforeSend:要求為Function類型的參數,發送請求前可以修改XMLHttpRequest對象的函數,例如添加自定義HTTP頭。在beforeSend中如果返回false可以取消本次ajax請求。XMLHttpRequest對象是惟一的參數。
    function(XMLHttpRequest){
       this;   //調用本次ajax請求時傳遞的options參數
    }
  1. complete:要求為Function類型的參數,請求完成后調用的回調函數(請求成功或失敗時均調用)。
    • 參數:XMLHttpRequest對象和一個描述成功請求類型的字符串。
    function(XMLHttpRequest, textStatus){
       this;    //調用本次ajax請求時傳遞的options參數
    }
  1. success:要求為Function類型的參數,請求成功后調用的回調函數,有兩個參數。
    1. 由服務器返回,並根據dataType參數進行處理后的數據。
    2. 描述狀態的字符串。
   function(data, textStatus){
      //data可能是xmlDoc、jsonObj、html、text等等
      this;  //調用本次ajax請求時傳遞的options參數
  1. error:要求為Function類型的參數,請求失敗時被調用的函數。該函數有3個參數,即XMLHttpRequest對象、錯誤信息、捕獲的錯誤對象(可選)。
    ajax事件函數如下:
      function(XMLHttpRequest, textStatus, errorThrown){
         //通常情況下textStatus和errorThrown只有其中一個包含信息
         this;   //調用本次ajax請求時傳遞的options參數
      }
    
  2. contentType:要求為String類型的參數,當發送信息至服務器時,內容編碼類型默認為"application/x-www-form-urlencoded"。該默認值適合大多數應用場合。
  3. dataFilter:要求為Function類型的參數,給Ajax返回的原始數據進行預處理的函數。提供data和type兩個參數。data是Ajax返回的原始數據,type是調用jQuery.ajax時提供的dataType參數。函數返回的值將由jQuery進一步處理。
    function(data, type){ //返回處理后的數據 return data; }
  4. global:要求為Boolean類型的參數,默認為true。表示是否觸發全局ajax事件。設置為false將不會觸發全局ajax事件,ajaxStart或ajaxStop可用於控制各種ajax事件。
  5. ifModified:要求為Boolean類型的參數,默認為false。僅在服務器數據改變時獲取新數據。服務器數據改變判斷的依據是Last-Modified頭信息。默認值是false,即忽略頭信息。
  6. jsonp:要求為String類型的參數,在一個jsonp請求中重寫回調函數的名字。該值用來替代在"callback=?"這種GET或POST請求中URL參數里的"callback"部分,例如{jsonp:'onJsonPLoad'}會導致將"onJsonPLoad=?"傳給服務器。
  7. username:要求為String類型的參數,用於響應HTTP訪問認證請求的用戶名。
  8. password:要求為String類型的參數,用於響應HTTP訪問認證請求的密碼。
  9. processData:要求為Boolean類型的參數,默認為true。默認情況下,發送的數據將被轉換為對象(從技術角度來講並非字符串)以配合默認內容類型"application/x-www-form-urlencoded"。如果要發送DOM樹信息或者其他不希望轉換的信息,請設置為false。
  10. scriptCharset:要求為String類型的參數,只有當請求時dataType為"jsonp"或者"script",並且type是GET時才會用於強制修改字符集(charset)。通常在本地和遠程的內容編碼不同時使用。

案例代碼:

$(function(){
    $('#send').click(function(){
         $.ajax({
             type: "GET",
             url: "test.json",
             data: {
               username:$("#username").val(), content:$("#content").val()
               },
             dataType: "json",
             success: function(data){
                         $('#resText').empty();   //清空resText里面的所有內容
                         var html = '';
                         $.each(data, function(commentIndex, comment){
                               html += '<div class="comment"><h6>' + comment['username']
                                         + ':</h6><p class="para"' + comment['content']
                                         + '</p></div>';
                         });
                         $('#resText').html(html);
                      }
         });
    });
});


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM