AJAX 簡單講解

AJAX(Asynchronous Javascript And XML:「異步JavaScript和XML」)

AJAX 已是老生常談的話題了,它最先起源於1997年,由 Microsoft 發明了其中的關鍵技術並由 Google 將其發揚光大。爲何是 Google 呢,這又是一個悲傷的故事,事實上在1995年 Microsoft 成功推出 IE5 之際就已經開始支持 XmlHttpRequset 對象,使人遺憾的是 Microsoft 高層沒有看到它的前景,以致於後來者 Google 成爲 AJAX 技術的最卓越的推進者和實踐者,從而奠基 Google 在 AJAX 發展史上的領先地位。javascript

  • 從如今的角度html

    • 提高用戶體驗java

      • 雖然不能增長數據下載的速度和減小下載的數據,但能夠減緩等待的過程ajax

    • 對傳統 B/S 軟件的衝擊json

  • 從將來的角度跨域

    • 將來本地化轉爲雲端的趨勢(這裏已經不算是將來了,畢竟已經基本實現了雲端)瀏覽器

從1997這個關鍵詞上咱們就知道 AJAX 並非一種新的技術,距今已經19年過去了 AJAX 的每次修訂依然沒有突破性的改變,由本來存在的幾種技術的組成的聚合而成:安全

  • 基於 XmlHttpRequest 對象服務器

    • 經過 XMLHttpRequest 來和服務器進行異步通訊cookie

  • 基於 WEB 標準

    • 使用 CSS、HTML(XHTML)呈現視覺效果

    • 操做 DOM 模型進行交互和動態呈現

    • 使用 JAVASCRIPT 綁定和調用等

XMLHttpRequest

XMLHttpRequest 是 AJAX 的核心機制,XMLHttpRequest 最先出如今 IE5 中,是一種支持異步請求的技術(即 javascript 異步向服務器提出請求和處理響應,而不阻塞線程,以達到無刷新的效果)。

以上是很官方的對 XMLHttpRequest 的解釋,這裏再也不重複造輪子,下面介紹一些簡單的 XMLHttpRequest 屬性:

  • onreadystatechange:每次狀態改變所觸發事件的事件處理程序。

  • responseText:從服務器進程返回數據的字符串形式。

  • responseXML:從服務器進程返回的DOM兼容的文檔數據對象。

  • responseBody:

  • status:從服務器返回的數字代碼,好比常見的 404(未找到)和 200(已就緒)。

  • status Text:伴隨狀態碼的字符串信息。

  • readyState:對象狀態值。

    • 0(未初始化):對象已創建,可是還沒有初始化(還沒有調用 open 方法)。

    • 1(初始化):對象已創建,還沒有調用send方法。

    • 2(發送數據):send 方法已調用,可是當前的狀態及http頭未知。

    • 3(數據傳送中):已接收部分數據,由於響應及 http 頭不全,這時經過 responseBody 和 responseText 獲取部分數據會出現錯誤。

    • 4(完成):數據接收完畢,此時能夠經過經過 responseXml 和 responseText 獲取完整的迴應數據。

但因爲不一樣瀏覽器之間存在差別,因此 JAVASCRIPT 建立一個 XMLHttpRequest 對象須要不一樣的方法。這個差別主要體如今 IE 和其它瀏覽器之間,JAVASCRIPT 函數首先檢查 XMLHttpRequest 的總體狀態而且保證它已經完成,而後才能夠執行後續操做,其中涉及到的一些方法以下:

  • open

    • 向服務器提交數據的類型,即post仍是get。

    • 請求的url地址和傳遞的參數

    • 傳輸方式,false爲同步,true爲異步。默認爲true

      • 同步:同步方式(false),客戶機就要等到服務器返回消息後纔去執行其餘操做。

      • 異步:異步通訊方式(true),客戶機就不等待服務器的響應。

  • send

    • 發送請求。

  • setRequestHeader

    • 設置請求頭,如 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

在 AJAX 的總體工做流程中,咱們將服務器端的 API 接口當作一個簡單的數據接口,它接受由XMLHttpRequest向服務器端發送的請求信息並返回純文本流(XML、Html、string、DataSet、json 或 Javascript 代碼)。

/**
     * 使用原生js封裝ajax
     * 兼容xhr對象
     */
    function createXHR(){
        if(typeof XMLHttpRequest != "undefined"){ // 非IE6瀏覽器
            return new XMLHttpRequest();
        }else if(typeof ActiveXObject != "undefined"){   // IE6瀏覽器
            var version = [
                "MSXML2.XMLHttp.6.0",
                "MSXML2.XMLHttp.3.0",
                "MSXML2.XMLHttp",
            ];
            for(var i = 0; i < version.length; i++){
                try{
                    return new ActiveXObject(version[i]);
                }catch(e){
                    //todo
                }
            }
        }else{
            throw new Error("您的系統或瀏覽器不支持XHR對象!");
        }
    }
    /**
     * 仍然須要更改 on 2015/11/18.
     * 異步的時候須要觸發onreadystatechange事件
     * readyStatus=4 即數據已經發送完畢
     * status=200 一切已經就緒
     */
    var xhr = createXHR();
    xhr.onreadystatechange = function(){
        // 執行完成
        if(xhr.readyState == 4 && xhr.status==200){
            //HTTP響應已經徹底接收才調用
            callBack();
        }
    }

XHR2 (XMLHttpRequest Level2)

目前仍有一些瀏覽器沒有實現 XHR2,因此在應用 AJAX 進行跨域訪問以前,首先檢測該瀏覽器是否支持跨域訪問:

if(typeof xhr.withCredentials!=undefined){
        //瀏覽器支持 xhr2 。
    }else{
        //瀏覽器支持不 xhr2 。
    }

XHR2 提供一系列新事件,在 XHR1 中咱們通常只應用 onreadystatechange,而後檢查狀態值再決定下一步操做,XHR2 提供 onload 回調函數簡化了這一步驟,在接收完數據的時候便可觸發。

xhr.onload=function(){
        //加載完成,進行下一步 todo。
    }

XHR2 的 onprogress事件的回調函數的事件參數有兩個重要屬性:loaded和total,用來計算百分值。

xhr.onprogress=function(e){
        console.log('Dwonloading:'+Math.ceil(e.loaded/e.total*100)+'%');
    }

XDomianRequest

XDomainRequest.aspx) 與 XHR2 功能上相似,且在 XHR2 以前出現,在 IE 中 XDomainRequest 和 XMLHttpRequest 是兩個不一樣的對象,

var xhr = new XDomainRequest();
    xhr.onprogress=function(e){
        console.log('Dwonloading:'+xhr.responseText.length);
    };
    xhr.onload=function(){
        //todo
    }

關注點:

  • IE 中 progress.aspx) 事件不具有進度功能,當每次 onprogress 觸發時能夠得到不完整的 responseText,但沒法肯定整體大小,因此不能肯定下載進度。

  • 不具有 upload 對象及其事件方法。

  • XDomainRequest.onprogress 事件是每接收到一個數據包觸發一次。

XMLHttpRequest 取捨之道

「魚,我所欲也,熊掌亦我所欲也;兩者不可得兼,舍魚而取熊掌者也」,XMLHttpRequest 實現了頁面無刷新更新數據,從而提高用戶體驗,減小頁面總體的請求次數,減輕服務器和帶寬的壓力,但同時 XMLHttpRequest 也破壞了瀏覽器的後退機制(解決辦法:經過建立或使用一個隱藏的IFRAME來重現頁面上的變動)、破壞了程序的異常機制、違背了url和資源定位的初衷、不經意間會暴露比之前更多的數據和服務器邏輯、跨站點腳步攻擊、SQL注入攻擊和基於credentials的安全漏洞等等問題。

另外,有一些須要注意的地方

  • 異步並不等於即時

  • XMLHttpRequest 發送請求(URL長度不到2K,可使用GET請求數據,GET相比POST更快速)

    • POST 類型請求要發送兩個 TCP 數據包。

      • 先發送文件頭。

      • 再發送數據。

    • GET 類型請求只須要發送一個 TCP 數據包。

      • 取決於你的 cookie 數量。

以及:

因爲同源策略的限制,XHR(XMLHttpRequest)對象不能直接與非同源的網站進行數據交互,那麼如何安全併合乎規則的突破這一限制呢?

在 HTML5 的概念造成以後,W3C 於2008年2月提出 XMLHttpRequest Level 2 (簡稱 XHR2)草案用以實現了跨域訪問,全新的事件,請求進度、響應進度以及其餘的一些新功能。與此同時 IE 也提出了 XDomianRequest ,XDomianRequest在功能上於 XHR2 相似。

瀏覽器檢查 Access-Control-Allow-Origin,具體可參考Http Access Control

相關文章
相關標籤/搜索