現在已經準備開始使用XMLHttpRequest對象了。我們剛剛討論了如何建立這個對象,下面來看如何向伺服器發送請求,以及如何處理伺服器的響應。
最簡單的請求是,不以查詢參數或提交表單資料的形式向伺服器發送任何資訊。在實際中,往往都希望向伺服器發送一些資訊。
使用XMLHttpRequest對象發送請求的基本步驟如下:
1. 為得到XMLHttpRequest對象執行個體的一個引用,可以建立一個新的執行個體,也可以訪問包含有XMLHttpRequest執行個體的一個變數。
2. 告訴XMLHttpRequest對象,哪個函數會處理XMLHttpRequest對象狀態的改變,為此要把對象的onreadystatechange屬性設定為指向JavaScript函數的指標。
3. 指定請求的屬性。XMLHttpRequest對象的open()方法會指定將發出的請求。open()方法取3個參數:一個是指示所用方法(通常是GET或POST)的串;一個是表示目標資源URL的串;一個是Boolean值,指示請求是否是非同步。
4. 將請求發送給伺服器。XMLHttpRequest對象的send()方法把請求發送到指定的目標資源。send()方法接受一個參數,通常是一個串或一個DOM對象。這個參數作為請求體的一部分發送到目標URL。當向send()方法提供參數時,要確保open()中指定的方法是POST。如果沒有資料作為請求體的一部分被發送,則使用null。
這些步驟很直觀:你需要XMLHttpRequest對象的一個執行個體,要告訴它如果狀態有變化該怎麼做,還要告訴它向哪裡發送請求以及如何發送請求,最後還需要指導XMLHttpRequest發送請求。不過,除非你對C或C++很瞭解,否則可能不明白函數指標(function pointer)是什麼意思。
函數指標與任何其他變數類似,只不過它指向的不是像串、數字、甚至對象執行個體之類的資料,而是指向一個函數。在JavaScript中,所有函數在記憶體中都編有地址,可以使用函數名引用。這就提供了很大的靈活性,可以把函數指標作為參數傳遞給其他函數,或者在一個對象的屬性中儲存函數指標。
對於XMLHttpRequest對象,onreadystatechange屬性儲存區了回呼函數的指標。當XMLHttpRequest對象的內部狀態發生變化時,就會調用這個回呼函數。當進行了非同步呼叫,請求就會發出,指令碼立即繼續處理(在指令碼繼續工作之前,不必等待請求結束)。一旦發出了請求,對象的readyState屬性會經過幾個變化。儘管針對任何狀態都可以做一些處理,不過你最感興趣的狀態可能是伺服器響應結束時的狀態。通過設定回呼函數,就可以有效地告訴XMLHttpRequest對象:“只要響應到來,就調用這個函數來處理響應。”
2.6.1 簡單請求的樣本
第一個樣本很簡單。這是一個很小的HTML頁面,只有一個按鈕。點擊這個按鈕會初始化一個發至伺服器的非同步請求。伺服器將發回一個簡單的靜態文字檔作為響應。在處理這個響應時,會在一個警告視窗中顯示該靜態文字檔的內容。代碼清單2-4顯示了這個HTML頁面和相關的JavaScript。
代碼清單2-4 simpleRequest.html頁面
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Simple XMLHttpRequest</title>
<script type="text/javascript">
var xmlHttp;
function createXMLHttpRequest() {
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}
function startRequest() {
createXMLHttpRequest();
xmlHttp.onreadystatechange = handleStateChange;
xmlHttp.open("GET", "simpleResponse.xml", true);
xmlHttp.send(null);
}
function handleStateChange() {
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
alert("The server replied with: " + xmlHttp.responseText);
}
}
}
</script>
</head>
<body>
<form action="#">
<input type="button" value="Start Basic Asynchronous Request"
onclick="startRequest();"/>
</form>
</body>
</html>