什么是 AJAX?
AJAX (異步 JavaScript 和 XML) 是個新產(chǎn)生的術(shù)語,專為描述JavaScript的兩項強大性能.這兩項性能在多年來一直被網(wǎng)絡(luò)開發(fā)者所忽略,直到最近Gmail, Google suggest和google Maps的橫空出世才使人們開始意識到其重要性.
這兩項被忽視的性能是:
無需重新裝載整個頁面便能向服務(wù)器發(fā)送請求.
對XML文檔的解析和處理.
步驟 1 – "請!" --- 如何發(fā)送一個HTTP請求
為了用JavaScript向服務(wù)器發(fā)送一個HTTP請求, 需要一個具備這種功能的類實例. 這樣的類首先由Internet Explorer以ActiveX對象引入, 被稱為XMLHTTP. 后來Mozilla, Safari 和其他瀏覽器紛紛仿效, 提供了XMLHttpRequest類,它支持微軟的ActiveX對象所提供的方法和屬性.
因此, 為了創(chuàng)建一個跨瀏覽器的這樣的類實例(對象), 可以應(yīng)用如下代碼:
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
http_request = new ActiveXObject("Microsoft.XMLHTTP");
}
如果服務(wù)器的響應(yīng)沒有XML mime-type header,某些Mozilla瀏覽器可能無法正常工作. 為了解決這個問題, 如果服務(wù)器響應(yīng)的header不是text/xml,可以調(diào)用其它方法修改該header.
http_request = new XMLHttpRequest();
http_request.overrideMimeType(‘text/xml‘);
http_request.onreadystatechange = nameOfTheFunction;
注意:在函數(shù)名后沒有括號,也無需傳遞參數(shù).另外還有一種方法,可以在扉頁(fly)中定義函數(shù)及其對響應(yīng)要采取的行為,如下所示:
http_request.onreadystatechange = function(){
// do the thing
};
http_request.open(‘GET‘, ‘http://www.example.org/some.file‘, true);
http_request.send(null);
第二個參數(shù)是請求頁面的URL.由于自身安全特性的限制,該頁面不能為第三方域名的頁面.同時一定要保證在所有的頁面中都使用準(zhǔn)確的域名,否則調(diào)用open()會得到"permission denied"的錯誤提示.一個常見的錯誤是訪問站點時使用domain.tld,而當(dāng)請求頁面時,卻使用www.domain.tld.
第三個參數(shù)設(shè)置請求是否為異步模式.如果是TRUE, JavaScript函數(shù)將繼續(xù)執(zhí)行,而不等待服務(wù)器響應(yīng).這就是"AJAX"中的"A".
如果第一個參數(shù)是"POST",send()方法的參數(shù)可以是任何想送給服務(wù)器的數(shù)據(jù). 這時數(shù)據(jù)要以字符串的形式送給服務(wù)器,如下所示:
name=value&anothername=othervalue&so=on
步驟 2 – "收到!" --- 處理服務(wù)器的響應(yīng)
當(dāng)發(fā)送請求時,要提供指定處理響應(yīng)的JavaScript函數(shù)名.
http_request.onreadystatechange = nameOfTheFunction;
我們來看看這個函數(shù)的功能是什么.首先函數(shù)會檢查請求的狀態(tài).如果狀態(tài)值是4,就意味著一個完整的服務(wù)器響應(yīng)已經(jīng)收到了,您將可以處理該響應(yīng).if (http_request.readyState == 4) {
// everything is good, the response is received
} else {
// still not ready
}
0 (未初始化)
1 (正在裝載)
2 (裝載完畢)
3 (交互中)
4 (完成)
接著,函數(shù)會檢查HTTP服務(wù)器響應(yīng)的狀態(tài)值. 完整的狀態(tài)取值可參見 W3C site. 我們著重看值為200 OK的響應(yīng).
if (http_request.status == 200) {
// perfect!
} else {
// there was a problem with the request,
// for example the response may be a 404 (Not Found)
// or 500 (Internal Server Error) response codes
}
http_request.responseText – 以文本字符串的方式返回服務(wù)器的響應(yīng)
http_request.responseXML – 以XMLDocument對象方式返回響應(yīng).處理XMLDocument對象可以用JavaScript DOM函數(shù)
步驟 3 – "萬事俱備!" - 簡單實例
我們現(xiàn)在將整個過程完整地做一次,發(fā)送一個簡單的HTTP請求. 我們用JavaScript請求一個HTML文件, test.html, 文件的文本內(nèi)容為"I‘m a test.".然后我們"alert()"test.html文件的內(nèi)容.
<script type="text/javascript" language="javascript">
var http_request = false;
function makeRequest(url) {
http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType(‘text/xml‘);
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) {
alert(‘Giving up :( Cannot create an XMLHTTP instance‘);
return false;
}
http_request.onreadystatechange = alertContents;
http_request.open(‘GET‘, url, true);
http_request.send(null);
}
function alertContents() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
alert(http_request.responseText);
} else {
alert(‘There was a problem with the request.‘);
}
}
}
</script>
<span
style="cursor: pointer; text-decoration: underline"
onclick="makeRequest(‘test.html‘)">
Make a request
</span>
本例中:
用戶點擊瀏覽器上的"請求"鏈接;
接著函數(shù)makeRequest()將被調(diào)用.其參數(shù) – HTML文件test.html在同一目錄下;
這樣就發(fā)起了一個請求.onreadystatechange的執(zhí)行結(jié)果會被傳送給alertContents();
alertContents()將檢查服務(wù)器的響應(yīng)是否成功地收到,如果是,就會"alert()"test.html文件的內(nèi)容.
步驟 4 – "X-文檔" --- 處理XML響應(yīng)
在前面的例子中,當(dāng)服務(wù)器對HTTP請求的響應(yīng)被收到后,我們會調(diào)用請求對象的reponseText屬性.該屬性包含了test.html文件的內(nèi)容.現(xiàn)在我們來試試responseXML屬性.
首先,我們新建一個有效的XML文件,后面我們將使用這個文件.該文件(test.xml)源代碼如下所示:
<?xml version="1.0" ?>
<root>
I‘m a test.
</root>
...
onclick="makeRequest(‘test.xml‘)">
...
var xmldoc = http_request.responseXML;
var root_node = xmldoc.getElementsByTagName(‘root‘).item(0);
alert(root_node.firstChild.data);
這里,我們使用了responseXML提供的XMLDocument對象并用DOM方法獲取存于XML文件中的內(nèi)容.