Ajax初步理解

謙行發表於2013-08-06

最近在專案中經常會使用Ajax技術,用法上倒是熟練了,但是隻知其然,不知其所以然,抽時間讀了讀JavaScript高階程式設計中關於Ajax的介紹有了些初步的理解,在此總結一下。

什麼是Ajax

Ajax是Asynchronous JavaScript and XML的縮寫,這一技術能夠向伺服器請求額外的資料而無需解除安裝整個頁面,會帶來良好的使用者體驗。傳統的HTTP請求流程大概是這樣的,瀏覽器向伺服器傳送請求-〉伺服器根據瀏覽器傳來資料生成response-〉伺服器把response返回給瀏覽器-〉瀏覽器重新整理整個頁面顯示最新資料,這個過程是同步的,順序執行。

AJAX 在瀏覽器與 Web 伺服器之間使用非同步資料傳輸(HTTP 請求)從伺服器獲取資料,這裡的非同步是指脫離當前瀏覽器頁面的請求、載入等單獨執行,這意味著可以在不重新載入整個網頁的情況下,通過JavaScript接受伺服器傳來的資料,然後操作DOM將新資料對網頁的某部分進行更新,使用Ajax最直觀的感受是向伺服器獲取新資料不需要重新整理頁面等待了。

XMLHttpRequest 物件

Ajax的核心是JavaScript物件XmlHttpRequest,這個物件為向伺服器傳送請求和解析伺服器響應提供了流暢的介面。XmlHttpRequest可以使用JavaScript向伺服器提出請求並處理響應,而不阻塞使用者。

XHR物件由IE5率先引入,在IE5中XHR物件是通過MSXML庫中一個ActiveX物件實現的,根據IE版本不同可能會遇到不同版本XHR物件,而IE7+與其它現代瀏覽器均支援原生的XHR物件,在這些瀏覽器中我們只需使用XMLHttpRequest建構函式就可以構造XHR物件,因此一個瀏覽器相容的建立XHR物件的函式寫法大概是這個樣子

<script type="text/javascript">
            function createXHR(){
                var xhr = null;
                try {
                    // Firefox, Opera 8.0+, Safari,IE7+
                    xhr = new XMLHttpRequest();
                }
                catch (e) {
                    // Internet Explorer 
                    try {
                        xhr = new ActiveXObject("Msxml2.XMLHTTP");
                    }
                    catch (e) {
                        try {
                            xhr = new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        catch (e) {
                            xhr = null;
                        }
                    }
                }
                return xhr;
            }
        </script>

XHR物件用法

XHR物件有兩個重要方法 open與send

image

在使用XHR物件時要呼叫的第一個方法是open方法,呼叫方式:xhr.open(“get”,”default.aspx”,true); 這段程式碼會針對default.aspx頁面傳送get請求,關於這段程式碼有三點需要注意:

1. URL是相對於當前頁面的路徑,也可以使用絕對路徑

2. 呼叫open方法並不會真正的傳送請求,而是初始化一個請求準備傳送

3. 只能向同一個域中使用相同協議和埠的URL傳送請求,否則會因為安全原因報錯

要想把請求發往伺服器需要呼叫send方法,send方法接受一個引數,引數是請求主體要傳送的資料,如果不需要傳送資料則傳入null,在呼叫send方法之後請求被髮往伺服器,如下

xhr.send(null);

請求發往伺服器,伺服器根據請求生成響應(Response),傳回給XHR物件,在收到響應後相應資料會填充到XHR物件的屬性,有四個相關屬性會被填充:

1. responseText:作為響應主體被返回的文字

2. responseXML:如果響應內容的型別是”text/xml”或”application/xml”,這個屬性將儲存包含著相應資料的XML文件

3. status:響應的HTTP狀態(200,404,500等)

4. statusText:HTTP狀態說明

在收到響應後第一步是檢查響應狀態,確保響應是否成功返回(狀態為200),如果成功responseText和responseXML可以被訪問,為了確保響應有效,我們可以這樣檢查狀態碼

xhr.open('get','default.aspx,false'); //準備同步請求
xhr.send();
if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
            //do something
        }else{
            //error handler
        }

上面程式碼在傳送同步請求的時候沒問題,只有得到響應後才會執行檢查status語句,但是在非同步請求時,JavaScript會繼續執行,不等生成響應就檢查狀態碼,這樣我們不能保證檢查狀態碼語句是在得到響應後執行(實際上也幾乎不可能,伺服器再快一個HTTP請求也不會快過一條JavaScript執行數度),這時候我們可以檢查XHR物件的readyState屬性,該屬性表示請求/響應過程中的當前活動階段,每當readyState值改變的時候都會觸發一次onreadystatechange事件。

image

我們可以利用這個事件檢查每次readyState變化的值,當為4的時候表示所有資料準備就緒,有一點我們需要注意:必須在open方法之前指定onreadtstatechange事件處理程式。

 

 

var xhr =createXHR();
           xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    setContainer('Original Ajax: ' + xhr.responseText);
                }
            }
            xhr.open('get', 'ajax.aspx?action=getTime', true);
            xhr.send();

 

我們可以在接受響應之前呼叫abort方法取消非同步請求:xhr.abort();

HTTP Header

每個HTTP請求都會帶有Header資訊,XHR物件也提供了操作這請求Header和響應Header資訊的方法,在預設情況下,傳送HTTP請求還會傳送下列頭部資訊

1. Accept:瀏覽器能夠處理的內容型別

2. Accept-Charset:瀏覽器能夠處理的字符集

3. Accept-Encoding:瀏覽器能夠處理的壓縮編碼

4. Accept-Language:瀏覽器當前設定的語言

5. Connection:瀏覽器與伺服器的連線型別

6. Cookie:當前頁面的cookie

7. Referer:傳送請求的頁面的URI

可以使用setRequestHeader方法設定自定義的請求Header資訊,這個方法接受兩個引數:頭部欄位的名稱,頭部欄位的值。要想成功傳送頭部資訊,必須在呼叫open方法之後,呼叫send方法之前掉用setRequestHeader方法。

function getTime() {
            var xhr = createXHR();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    setContainer('Original Ajax: ' + xhr.responseText);
                }
            }
            xhr.open('get', 'ajax.aspx?action=getTime', true);
            xhr.setRequestHeader(myHeader,myValue)
            xhr.send();
        }

我們可以在伺服器端接收自定義Header然後做響應操作。同時在伺服器端也可以向瀏覽器傳送額外的資料,在沒有自定義資訊的情況下我們可以得到預設response header

1. Date:響應時間

2. Server:伺服器型別

3. Very:驗證Encoding型別

4.X-Power-By:語言

。。。

GET和POST請求

GET請求時最常見的請求型別,用於向伺服器查詢資訊,必要時可以將查詢字串引數放在URL尾部傳送給伺服器,如果引數有特殊字元必須正確編碼。我們上面使用的例子都是使用GET請求,非常簡單,向伺服器詢問資料,然後處理資料。

POST請求用於把資料作為主體向伺服器提交,POST請求主體可以包含多種格式資料,在open方法第一個引數傳入”POST”就可以初始化一個POST請求。傳送POST請求第二步就是向send方法傳輸資料引數,引數可以是xml或者字串,json等。

function getInfo() {
            var xhr = createXHR();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    setContainer('Original Ajax: ' + xhr.responseText);
                }
            }
            xhr.open('post', 'default.aspx', true);
            xhr.send('{name:"Byron",age:"24"}');
        }

最後

關於Ajax的總結就到這裡,本文介紹的是純JavaScript使用Ajax很是繁瑣複雜,很多優秀JavaScript框架都對JavaScript操作Ajax做了很好封裝處理,使用起來非常方便,最出名的是jQuery的ajax了,微軟也對Ajax做了很好的分裝處理,使其在ASP.NET頁面中使用起來相當簡單方便,相關知識可以看看ASP.NET中使用Ajax

相關文章