JavaScript第七章:Ajax
Ajax的優勢在於:對於頁面的請求以非同步方式傳送到伺服器。而伺服器不會用整個頁面來響應請求,它會在後臺處理請求,與此同時使用者還能繼續瀏覽頁面並與頁面互動。你的指令碼則可以按需載入和建立頁面內容,而不會打斷使用者的瀏覽體驗。
1.XMLHttpRequest物件
這個物件充當著瀏覽器的指令碼(客戶端)與伺服器之間的中間人的角色。JavaScript通過這個物件可以自己傳送請求,同時自己處理響應。
①不同瀏覽器實現XMLHttpRequest物件的方式不一樣,需要些不同的程式碼分支。
<!DOCTYPE html> <head> <meta charset="utf-8"/> <title>Ajax</title> </head> <body> <div id="new"></div> <script src="scripts/addLoadEvent.js"></script> <script src="scripts/getHTTPObject.js"></script> <script src="scripts/getNewContent.js"></script> </body> </html>
微軟在IE5中以ActiveX物件形式實現了名為XMLHTTP的物件,在IE中建立新的物件要使用下列程式碼:
var request=new ActiveXObject("Msxml2.XMLHTTP.3.0");
其他瀏覽器則基於XMLHttpRequest來建立物件:
var request=new XMLHttpRequest();
不同IE版本中使用的XMLHTTP物件也不完全相同。因此getHTTPObject函式要這樣寫:
function getHTTPObject(){ if(typeof XMLHttpRequest=="undefined") XMLHttpRequest=function(){ try{ return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }catch(e){} try{ return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }catch(e){} try{ return new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){} return false; } return new XMLHttpRequest(); }
②XMLHttpRequest方法
XMLHttpRequest物件有許多方法,最常用的就是open方法。它用來指定伺服器上將要訪問的檔案,指定請求型別:GET、POST或SEND。第三個引數是用來指定請求是否以非同步的方式傳送和處理。
function getNewContent(){ var request=getHTTPObject(); if(request){ request.open("GET","example.txt",true); //頁面載入完成後,會發出一個GET請求,請求與ajax.js位於同一目錄的example.txt request.onreadystatechange=function(){ if(request.readyState==4){ var para=document.createElement("p"); var txt=document.createTextNode(request.responseText); para.appendChild(txt); document.getElementById('new').appendChild(para); } }; /*onreadyStatechange是一個事件處理函式,會在伺服器給XMLHttpRequest物件送回響應時 被觸發執行 */ request.send(null); /* 指定了請求的目標和如何處理響應,就可以用send方法傳送請求了 */ }else{ alert('Sorry,your browser doesn\'t support XMLHttpRequest'); } } addLoadEvent(getNewContent);
伺服器在向XMLHttpRequest物件發回響應時,該物件有許多屬性可用。瀏覽器會在不同階段更新readyState屬性的值,它有五個值:
- 0表示 未初始化
- 1表示 正在載入
- 2表示 載入完畢
- 3表示 正在互動
- 4表示 完成
只要readyState屬性的值變成了4,就可以訪問伺服器傳送回來的資料。
訪問伺服器傳送回來的資料要通過兩個屬性完成 ,一個是responseText屬性,這個屬性用於儲存文字字串形式的資料。另一個是responseXML屬性,用於儲存Content-Type頭部中指定為“text/xml”的資料,其實是一個DocumentFragment物件。而是用各種DOM方法來處理這個物件。
③非同步請求
非同步請求的一個容易被忽略的問題是非同步性,就是指令碼在傳送XMLHttpRequest請求,仍會繼續執行,不會等待響應返回。
為了證明這點,可以在request.onreadystatechange處理函式中和getNewContent函式的最後各新增一個警告框。
function getNewContent(){
var request=getHTTPObject();
if(request){
request.open("GET","example.txt",true);
request.onreadystatechange=function(){
if(request.readyState==4){
alert("Reponse Received")
var para=document.createElement("p");
var txt=document.createTextNode(request.responseText);
para.appendChild(txt);
document.getElementById('new').appendChild(para);
}
};
request.send(null);
}else{
alert('Sorry,your browser doesn\'t support XMLHttpRequest');
}
alert("Function Done");
}
載入下頁面,很可能Function Done的警告框會先於Response Received的警告框出現。這就證明了指令碼不會等待send的響應,而是會繼續執行。
2.漸進增強與Ajax
能通過Ajax實現的應用一定能通過非Ajax技術來實現。
如果一開始設計就以Ajax為起點,那麼以後很難把它從成品站點中剝離出來,再額外提供一個不適用Ajax的版本。但是,如果一開始應用就是基於老式的頁面重新整理機制構建的,那麼就可以在既有框架上,用Ajax攔住傳送到伺服器的請求,並將請求轉交給XMLHttpRequest物件處理。這種情況下,Ajax功能就扮演了一個位於常規站點之上的層。
因此,構建Ajax網站的最好辦法,也是先構建一個常規的網站,然後Hijax它。