天天看點

艾偉:詳解AJAX核心 —— XMLHttpRequest 對象 (上)

我要說的内容都是非常基礎的内容,高手就免看了,如果看了歡迎給點意見啊。新手或者對低層還不是很了解的人可以看看,幫助了解與記憶。

XMLHttpRequest 對象是AJAX功能的核心,要開發AJAX程式必須從了解XMLHttpRequest 對象開始。

了解XMLHttpRequest 對象就先從建立XMLHttpRequest 對象開始,在不同的浏覽器中建立XMLHttpRequest 對象使用不同的方法:

先看看IE建立XMLHttpRequest 對象的方法(方法1):

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  //使用較新版本的 IE 建立 IE 相容的對象(Msxml2.XMLHTTP)

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用較老版本的 IE 建立 IE 相容的對象(Microsoft.XMLHTTP)

而 Mozilla、Opera、Safari 和大部分非IE的浏覽器都使用下面這種方法(方法2)建立XMLHttpRequest 對象:

var xmlhttp = new XMLHttpRequest();

實際上Internet Explorer 使用了一個名為 XMLHttp 的對象,而不是 XMLHttpRequest 對象,而 Mozilla、Opera、Safari 和 大部分非 Microsoft 浏覽器都使用的是後者(下文統稱 XMLHttpRequest 對象)。IE7開始也開始使用XMLHttpRequest 對象了。

在建立 XMLHttpRequest 對象的時候如果不同的浏覽器使用了不正确的方法浏覽器都将會報錯,并且無法使用該對象。是以我們需要一種可以相容不同浏覽器的建立XMLHttpRequest 對象的方法:

艾偉:詳解AJAX核心 —— XMLHttpRequest 對象 (上)
艾偉:詳解AJAX核心 —— XMLHttpRequest 對象 (上)

建立相容多浏覽器的 XMLHttpRequest 對象方法

var xmlhttp = false; //建立一個新變量 request 并指派 false。使用 false 作為判斷條件,它表示還沒有建立 XMLHttpRequest 對象。 

function CreateXMLHttp(){

    try{

        xmlhttp = new XMLHttpRequest();  //嘗試建立 XMLHttpRequest 對象,除 IE 外的浏覽器都支援這個方法。

    }

    catch (e){

        try{

            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  //使用較新版本的 IE 建立 IE 相容的對象(Msxml2.XMLHTTP)

        }

        catch (e){

            try{

              xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用較老版本的 IE 建立 IE 相容的對象(Microsoft.XMLHTTP)。

            }

            catch (failed){

                  xmlhttp = false;  //如果失敗則保證 request 的值仍然為 false。

    return xmlhttp;

}

判斷是否建立成功就很簡單了

if (!xmlhttp){

 //建立XMLHttpRequest 對象失敗!

else{

 //建立成功!

建立好了XMLHttpRequest 對象我們再來看看這個對象的方法、屬性以及最重要的onreadystatechange事件句柄吧。

方法:

open() 說明:初始化 HTTP 請求參數,例如 URL 和 HTTP 方法,但是并不發送請求。

abort() 說明:取消目前響應,關閉連接配接并且結束任何未決的網絡活動。

getAllResponseHeaders() 說明:把 HTTP 響應頭部作為未解析的字元串傳回。

getResponseHeader() 說明:傳回指定的 HTTP 響應頭部的值。

send() 說明:發送 HTTP 請求,使用傳遞給 open() 方法的參數,以及傳遞給該方法的可選請求體。

setRequestHeader() 說明:向一個打開但未發送的請求設定或添加一個 HTTP 請求。

屬性:

readyState 說明:HTTP 請求的狀态。

responseText 說明:目前為止為伺服器接收到的響應體(不包括頭部),或者如果還沒有接收到資料的話,就是空字元串。

responseXML 說明:對請求的響應,解析為 XML 并作為 Document 對象傳回。

status 說明:由伺服器傳回的 HTTP 狀态代碼。

statusText 說明:這個屬性用名稱而不是數字指定了請求的 HTTP 的狀态代碼。

onreadystatechange 是每次 readyState 屬性改變的時候調用的事件句柄函數。

下面從發送請求并處理請求結果的過程來了解一下XMLHttpRequest 對象吧。

發送請求之前自然就是生成一個XMLHttpRequest 對象,代碼上面有了就不多寫了。

生成一個XMLHttpRequest 對象

var xmlhttp = CreateXMLHttp();

建立好XMLHttpRequest 對象了,那我們要送請求到哪個網站呢,就選擇部落格園首頁的RSS吧。那怎麼設定我要請求的網站位址呢,使用open()方法。

open(method, url, async, username, password)

我們用的就是這個了。

xmlHttp.open("get","http://www.cnblogs.com",true);

get參數表示用get方法,第二個自然就是目标位址,部落格園首頁,第三個就是表示是否異步了,我們當然使用true了。具體的參數說明還都可以到http://www.w3school.com.cn上面看了。

好了,目标定好了,怎麼發送呢。用send()方法。

send(body),send()方法隻有一個參數,表示DOM對象,這個DOM對象需要說明的内容很多,下次說,今天我們隻要寫

xmlhttp.send(null);

就可以了。好了,發送了,那怎麼處理傳回的結果呢,這個時候就用到XMLHttpRequest 對象最重要的東西了,那就是onreadystatechange事件句柄。什麼意思呢,那就需要說明一下XMLHttpRequest 對象的readyState了,readyState有5種狀态,分别用數字的 0 到 4 來表示。

狀态      名稱            描述

0      Uninitialized       初始化狀态。XMLHttpRequest 對象已建立(未調用open()之前)或已被 abort() 方法重置。

1      Open           open() 方法已調用,但是 send() 方法未調用。請求還沒有被發送。

2      Sent            Send() 方法已調用,HTTP 請求已發送到 Web 伺服器。未接收到響應。

3      Receiving      所有響應頭部都已經接收到。響應體開始接收但未完成。

4      Loaded         HTTP 響應已經完全接收。

但是需要注意的是,onreadystatechange事件句柄不同的浏覽器能處理的狀态并不一緻,IE和FireFox能處理1到4,而Safari能處理2到4的狀态,Opera 能處理3、4兩中狀态。0的狀态基本沒什麼用,因為建立了XMLHttpRequest 對象後都會馬上調用open() 方法,這時候狀态就變成1了,當然除非你要判斷對象是否已經被 abort() 取消,可是這樣的情況依然很少。大部分情況下判斷是不是4(已經接受完成)這個狀态就夠了。

好了,明白了readyState有5種狀态了,那處理傳回結果就是看狀态變更到不同的狀态我們做不同的處理就可以了,怎麼告訴XMLHttpRequest 對象狀态變化時讓誰來處理這個變化呢。有兩種寫法,一種是用匿名方法,另一種是指定方法,其實隻是不同的寫發,作用都一樣,看下代碼:

xmlhttp.onReadyStateChange = function (){

 //處理狀态變化的代碼

//或者

xmlhttp.onReadyStateChange = getResult;

function getResult(){

 ///處理狀态變化的代碼

//順便說一下,句柄的名稱比較長,可以這樣記憶 on ReadyState Change 表示在讀取狀态改變時

請求發送了,也指定處理方法了,怎麼擷取傳回的内容呢,有responseText和responseXML兩個屬性可供使用,responseXML是傳回對象,需要再解析,後面再說,這裡先用responseText,看看傳回什麼。

alert(xmlhttp.responseText); //看看是不是傳回了首頁的HTML代碼啊。是你就成功了。

整個過程是:建立XMLHttpRequest 對象 -> 指定發送位址及發送方法 -> 發送請求 -> 指定處理方法并處理傳回結果。但是需要注意,我們正常的思路了解是這樣的,可是onreadystatechange事件句柄指定處理方法需要在發送之前就指定好,否則無法處理狀态變化事件。

是以我們應該按照下面的流程來記憶:建立XMLHttpRequest 對象 -> 指定發送位址及發送方法 -> 指定狀态變化處理方法 -> 發送請求,請求發送後狀态變化了就會自動調用指定的處理方法。

好了,看看完成的代碼吧。

艾偉:詳解AJAX核心 —— XMLHttpRequest 對象 (上)
艾偉:詳解AJAX核心 —— XMLHttpRequest 對象 (上)

完成的代碼

    var xmlhttp = false; //建立一個新變量 request 并指派 false。使用 false 作為判斷條件,它表示還沒有建立 XMLHttpRequest 對象。 

    function CreateXMLHttp(){

            xmlhttp = new XMLHttpRequest();  //嘗試建立 XMLHttpRequest 對象,除 IE 外的浏覽器都支援這個方法。

                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");  //使用較新版本的 IE 建立 IE 相容的對象(Msxml2.XMLHTTP)

            catch (e){

                try{

                  xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //使用較老版本的 IE 建立 IE 相容的對象(Microsoft.XMLHTTP)。

                }

                catch (failed){

                      xmlhttp = false;  //如果失敗則保證 request 的值仍然為 false。

        return xmlhttp;

    xmlhttp = CreateXMLHttp();

    xmlhttp.open("get","http://www.cnblogs.com",true);

    xmlhttp.onReadyStateChange = getResult;

    xmlhttp.send(null);

    function getResult(){

        if(xmlhttp.readyState == 4){

            alert(xmlhttp.responseText);

把getResult()方法寫成下面這樣我覺的就真的OK了。

 function getResult(){

  if(xmlhttp.readyState == 4 && xmlhttp.status == 200){

   alert(xmlhttp.responseText);

  }

 }

好了,一個本來挺簡單的東西,被我寫的這麼多,好象很羅嗦。不過我覺的程式設計對基礎内容的了解很重要,現在很多時候開發AJAX的程式都使用很多JS的庫,不需要直接編寫這麼基礎的代碼。如使用著名的jQuery,但是如果我們對基礎的東西有很好的了解,那這些庫報告錯誤,或者出現問題我們可以很好很快的知道錯在哪裡,更快的做出改變使程式正常運作。

繼續閱讀