幾種Ajax技術

今天我來談談Ajax技術。web

Ajax是一種與服務器通訊而無需重載頁面的方法。數據能夠從服務器獲取或者發給服務器。json

Ajax和異步分不開,可是本文重點部分不是異步,而是對實現Ajax的技術進行總結。segmentfault

我簡要羅列一下幾種常見的Ajax技術:跨域

  • 動態腳本注入和JSON-P瀏覽器

  • 圖片信標(Beacons)安全

  • XMLHttpRequest(XHR)技術服務器

接下來我簡要談談我對這幾種技術的理解。異步

<!--more-->函數

動態腳本注入

以前的文章中談到,<script>標籤做爲DOM的一部分,能夠由JavaScript調用DOM操做的接口動態建立。動態建立的<script>元素能夠爲其設置src屬性而且插入到DOM樹中。此時異步線程會並行的去加載src資源,等到資源加載完成以後,其中的字符會當作JavaScript語句執行。網站

該技術是一個hack技術,它利用了瀏覽器的特性。該特性能夠實現「無阻塞加載腳本」技術。更多細節能夠移步:無阻塞加載腳本的理解

除了在頁面初始化的時候可使用動態腳本注入,Ajax技術也可使用動態腳本注入的技術實現。動態腳本注入能夠從服務器中請求數據

首先咱們須要將待請求數據的細節放在src中。由於src對應一個url,瀏覽器會將這個url做爲GET請求發往相應的服務器,因此咱們將請求數據做爲查詢字符串寫入src

服務器在收到請求後,會返回數據。可是這個數據必須以一段JavaScript腳本的形式返回。緣由是瀏覽器收到響應數據後會將其當作JavaScript腳本執行。

也就是說,假設響應數據若是隻是簡單的xml或者json數據,對於動態腳本注入來講,沒有任何意義。

所以服務器收到動態腳本注入中的GET請求時,須要返回一個約定好的表示JavaScript腳本的字符串。這段腳本還須要處理瀏覽器端須要的數據,好比:

dosomething([{"x": 1, "y": "haha"}]);

這段字符串返回以後就會被執行。其中dosomething就是約定好的一個回調函數名。這個回調函數已經在以前的腳本中定義好。

另外,咱們還能夠將回調函數名稱做爲查詢字符串傳入,這樣服務器就能夠動態的將回調函數做爲響應數據中的一部分返回。

dosomething中的參數一個JSON數據,可是它在返回以後,會被當作JavaScript對象執行。因爲這種特性,使用JSON的動態腳本注入又能夠稱做所謂的「JSON-P」。

該技術還有兩個注意點:

  • 動態腳本注入技術能夠跨域訪問,不一樣域中返回的腳本可能截獲網站數據,致使安全問題,所以要當心使用。

  • 動態腳本注入技術不能發送POST等非GET請求。然而,有些瀏覽器對GET請求有諸多限制(好比url字符數的限制),所以須要POST請求的Ajax,請考慮其餘方法。

Beacons

Beacons技術很適合向服務器發送數據。

和上面的動態腳本注入相似,Beacons可使用特定的DOM元素,利用src屬性向服務器發送數據,可是不須要服務器返回數據。

咱們可使用一個Image對象,設置src以後,該請求會從服務器返回一個圖片(通常是一個1*1的透明圖片)。這是最經常使用的方法。

var url = "....";
var params = [
    "..",
    ".."
];

var img = new Image();
img.src = url + '?' + params.join('&');

若是響應中不須要任何數據,注意須要服務器設置狀態碼爲204 No Content

若是須要必定的消息返回,咱們能夠用一種變通的手法:設置返回圖片的寬度,不一樣的寬度表明不一樣的信息。這些信息能夠在Image對象的onload事件中監聽。

img.onload = function(){
    if (this.width === 1){
        // ...
    } else if (this.width === 2){
        // ...
    } // else if ...
}

和動態腳本注入相似,Beacons技術也有可跨域和沒法發送非GET請求的問題。

另外,也能夠利用<iframe>標籤來作相似的操做。

XMLHttpRequest

目前Ajax使用最多的技術手段就是利用XMLHttpRequest技術。

XMLHttpRequest是一個特殊的構造函數,這個構造函數不在ECMA標準內,可是各大瀏覽器對其均支持良好。

直接上代碼:

var xhr = new XMLHttpRequest();

var url = '...';

var data; // 接受響應主體
var header; // 接受響應頭
var status; // 接收狀態碼
var statusText; // 接收狀態信息

xhr.onreadystatechange = function(){ // 監聽readyState變化
    if (xhr.readyState === 4){       // 該值爲4,代表響應結束
        data = xhr.responseText;     // 獲取響應主體
        // or: data = xhr.responseXML; ...
        
        headers = xhr.getAllResponseHeaders(); // 獲取響應頭
        
        status = xhr.status; // 獲取狀態碼
        statusText = xhr.statusText; //獲取狀態信息
        
        // do something...
    }
}

xhr.open('GET', url, true);       // 開啓一個請求,true表示異步響應
xhr.setRequestHeader('..', '..'); // 設置請求頭
xhr.send(null);                   // 開始發送,參數是請求主體(用於POST請求)

XMLHttpRequest支持GET和POST請求,而且能夠輕鬆設置請求主體和部分請求頭,也能夠獲取響應主體和響應頭。雖然名稱叫XMLHttpRequest,可是事實上它支持各類不一樣的數據格式如JSON、HTML等。

可是注意,該技術是不能跨域訪問的,除非web服務器設置了容許跨域訪問策略。

另外一個值得注意的地方就是:readyState的值爲4,代表響應結束,可是咱們也能夠監聽其值爲3的狀況,該值代表響應正在進行,此時能夠獲取部分響應主體。
readyState的值爲012分別表示open()還沒有調用、open()已調用,和接收到頭信息。這些用途相對較小。

更多詳情,請參見MDN中關於XMLHttpRequest的解釋:連接

結束

相關文章
相關標籤/搜索