高級程序設計之Ajax實例講解

一前言 二XMLHttpRequest對象 XHR的用法 HTTP頭部信息 GET請求 POST請求 三XMLHttpRequest 2級 FormData 超時設定 overrideMimeType方法 四進度事件 load事件 progress事件

一、前言

這一技術能夠向服務器請求額外的數據而無須卸載頁面,會帶來更好的用戶體驗。

Ajax這一技術的核心是XMLHttpRequest對象(簡稱XHR)

XHR為向服務器發送請求和解析服務器相應提供瞭流暢的接口。能夠以異步方式從服務器取得更多信息,意味著用戶單擊後,可以不必刷新頁面也能取得新數據。也就是說,可以使用XHR對象取得新數據,然後 再通過DOM將新數據插入到頁面中。

雖然名字中包含XML的成分,但Ajax通信與數據格式無關;這種技術就是無需刷新即可從服務器取得數據,但不一定是XML數據。

二、XMLHttpRequest對象

瀏覽器差異導致在IE中可能會遇到三種不同版本的XHR對象

現在的瀏覽器大都支持原生的XHR對象

function createXHR(){
    if(typeof XMLHttpRequest !="undefined"){
        //創建XHR對象
        return new XMLHttpRequest();
    }
    else if(typeof ActiveXObject!="undefined"){
        //適用於IE7之前的版本
        if(typeof arguments.callee.activeXString !="string"){
            var versions=["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len;
            for(i=0,len=versions.length;i

XHR的用法

在使用XHR對象時,要調用的第一個方法是open(),它接受3個參數

要發送的請求的類型:get、post等

請求的url

表示是否異步發送請求的佈爾值

xhr.open("get","example.php",false);

調用open()方法並不會真正發送請求,而隻是啟動一個請求以備發送

隻能向同一個域中使用相同端口和協議的URL發送請求

send()方法

一個參數:要作為請求主體發送的數據;如果不需要通過請求主體發送數據,則必須傳入null

調用該方法後,請求就會被分派到服務器

在收到響應後,相應的數據會自動填充XHR對象的屬性

responseText:作為響應主體被返回的文本,無論內容類型是什麼

responseXML:

如果響應的內容類型是”text/xml”或”application/xml”,這個屬性中將保存包含著響應數據的XML DOM文檔

對於非XML數據,屬性值為null

status:響應的HTTP狀態

200:成功的標志。此時,responseText屬性的內容已經就緒,而且在內容類型正確的情況下,responseXML也應該能夠訪問瞭。

304:請求的資源並沒有被修改,可以直接使用瀏覽器中緩存的版本。也意味著響應是有效的。

statusText:HTTP狀態的說明

readyState屬性:表示請求/響應過程的當前活動階段

0:未初始化。尚未open()

1:啟動。調用open()

2:發送。調用send()

3:接收。已經接收到部分響應數據

4:完成。已經接收到全部響應數據,而且已經可以在客戶端使用瞭

隻要上述屬性的值發生改變,就會觸發一次readystatechange事件。必須在調用open()之前指定onreadtstatechange事件處理程序才能確保跨瀏覽器兼容性。

上述事件處理程序,不建議使用this對象。如果使用,在有的瀏覽器中會導致函數執行失敗,或者導致錯誤發生。因此,使用實際的xhr對象實例變量是較為可靠的一種方式。

在接收到響應之前還可以調用abort()方法來取消異步請求。之後xhr對象會停止觸發事件,而且也不再允許訪問任何與響應有關的對象屬性。在終止請求之後,還應該對XHR對象進行解引用操作。且不建議重用xhr對象。

xhr.abort();

var xhr=createXHR();
xhr.onreadystatechange=function(){
    if(xhr.readyState==4){
        if(xhr.status>=200&&xhr.status<300||xhr.status==304){
            alert(xhr.reasponseText);
        }
        else{
            alert("unsuccessful:"+xhr.status);
        }
    }
};
xhr.open("get","example.txt",true);
xhr.send(null);

HTTP頭部信息

每個HTTP請求和響應都會帶有相應的頭部信息。

默認情況下,在發送xhr請求的同時,還會發送下列頭部信息:

Accept:在瀏覽器能夠處理的內容類型 Accept-Charset:瀏覽器能夠顯示的字符集 Accept-Encoding:瀏覽器能夠處理的壓縮編碼 Accept-Language:瀏覽器當前設置的語言 Connection:瀏覽器與服務器之間連接的類型 Cookie:當前頁面設置的任何Cookie Host:發出請求的頁面所在的域 Referer:發出請求的頁面的URI User-Agent:瀏覽器的用戶代理字符串

使用setRequestHeader()方法,可以設置自定義的請求頭部信息。兩個參數

頭部字段的名稱 頭部字段的值 在open()之後,send()之前調用

xhr.open("get","example.php","true");
xhr.setRequestHeader("MyHeader","MyValue");
xhr.send(null);

服務器在接收到這種自定義的頭部信息後,可以執行相應的後續操作 建議使用自定義的頭部字段名稱,否則有可能會影響服務器的響應 調用xhr對象的getResponseHeader()方法

傳入頭部字段名稱 取得相應的響應頭部信息 調用getAllResponseHeaders()方法,可以取得一個包含所有頭部信息的長字符串

GET請求

最常用於向服務器查詢某些信息,可以將查詢字符串參數追加到URL的末尾,以便將信息發送給服務器。

對XHR而言,位於傳入open()方法的URL末尾的查詢字符串必須經過正確的編碼才行。

使用encodeURICompinent()進行編碼,然後才能放到URL的末尾;而且所有名值對都必須由和號(&)分隔

var url="example.php";
function addURLParam(url,name,value){
    url+=(url.indexOf("?")==-1?"?":"&");
    url+=encodeURIComonent(name)+"="+encodeURIComponent(value);
    return url;
}
//添加參數
url=addURLParam(url,"name","Mary");
//初始化請求
xhr.open("get",url,false);

POST請求

通常用於向服務器發送應該被保存的數據。

POST請求的主題可以包含非常多的數據,而且格式不限。

第一步,初始化一個POST請求

xhr.open("post","example.php",true);

第二步,向send()方法中傳入某些數據。可以傳入XML DOM文檔,傳入的文檔經序列化之後將作為請求主體被提交到服務器;也可以傳入任何想發送到服務器的字符串

服務器對POST請求和提交web表單的請求不會一視同仁。因此,服務器端必須有程序來讀取發送過來的原始數據。不過,可以使用XHR來模仿表單提交:

將Content-Type頭部信息設置為application/x-www-form-urlencoded,也就是表單提交時的內容類型 以適當的格式創建一個字符串

//把表單中的數據序列化之後發送給服務器
xhr.open("post","example.php",true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
var form=document.getElementById("user-info");
xhr.send(serialize(form));

三、XMLHttpRequest 2級

FormData

FormData為序列化表單以及創建與表單格式相同的數據(用於通過xhr傳輸)提供瞭便利

創建後可以添加數據,通過append()方法:

接收兩個參數:鍵和值 分別對應表單字段的名字和字段中包含的值 可以添加任意多個

通過向FormData構造函數中傳入表單元素,也可以用表單元素的數據預先向其中填入鍵值對

var data=new FormData(document.forms[0]);
data.append("name","mary");

創建瞭實例後,可以將它直接傳給XHR的send()方法

xhr.send(new FormData(form));

優點:不必設置請求頭部,xhr對象能夠識別傳入的數據類型是FormData的實例,並配置適當的頭部信息

超時設定

timeout屬性:在給其設置一個數值後,如果在規定的時間內瀏覽器還沒有接收到響應,那麼就會觸發timeout事件,進而會調用ontimeout事件處理程序。僅適用於ie8+

xhr.open("get","timeout.php",true);
xhr.timeout(1000);//1秒鐘
xhr.ontimeout=function(){
    alert("request did not return in a second.");
};
xhr.send(null);

overrideMimeType()方法

用於重寫XHR響應的MIME類型 必須在send()方法前調用,才能保證重寫響應的MIME類型

xhr.overrideMimeType("texe/xml");

四、進度事件

與客戶端服務器通信有關的事件

loadstart:在接收到響應數據的第一個字節時觸發 progress:在接收響應期間持續不斷地觸發 error:在請求發生錯誤時觸發 abort:在因為調用abort()方法而終止連接時觸發 load:在接收到完整的響應數據時觸發 loadend:在通信完成或者觸發load、error、或abort事件後觸發 每個請求都從loadstart事件開始,接下來是一或多個progress事件,然後觸發error、abort或load事件中的一個,最後以觸發loadend事件結束

load事件

不必檢查readystate屬性瞭,但是要檢查status屬性 event對象瀏覽器有差異性,所以還是要使用xhr對象變量

progress事件

事件處理程序會接收到一個event對象,其target屬性是xhr對象,包含三個額外的屬性:

lengthComputable:表示進度信息是否可用的佈爾值 position:表示已經接收的字節數 totalSize:表示根據Content-Length響應頭部確定的預期字節數

在open()方法之前調用onprogress事件處理程序

xhr.onprogress=function(event){
    var pstatus=document.getElementById("status");
    if(event.lengthComputable){
        pstatus.innerHTML="recived"+event.position+"of"+event.totalSize+"bytes";
    }
};
xhr.open("get","example.php",true);
xhr.send(null);

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *