2.6 如何發送簡單請求

現在已經準備開始使用XMLHttpRequest對象了。我們剛剛討論瞭如何創建這個對象,下面來看如何向服務器發送請求,以及如何處理服務器的響應。
最簡單的請求是,不以查詢參數或提交表單數據的形式向服務器發送任何信息。在實際中,往往都希望向服務器發送一些信息。
使用XMLHttpRequest對象發送請求的基本步驟如下:
1. 爲得到XMLHttpRequest對象實例的一個引用,可以創建一個新的實例,也可以訪問包含有XMLHttpRequest實例的一個變量。
2. 告訴XMLHttpRequest對象,哪個函數會處理XMLHttpRequest對象狀態的改變,爲此要把對象的onreadystatechange屬性設置爲指向JavaScript函數的指針。
3. 指定請求的屬性。XMLHttpRequest對象的open()方法會指定將發出的請求。open()方法取3個參數:一個是指示所用方法(通常是GETPOST)的串;一個是表示目標資源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"
                οnclick="startRequest();"/>
    </form>
</body>
</html>
服務器的響應文件simpleResponse.xml只有一行文本。點擊HTML頁面上的按鈕會生成一個警告框,其中顯示simpleResponse.xml文件的內容。在圖2-4中可以看到分別在Internet Explorer和Firefox中顯示的包含服務器響應的相同警告框。
對服務器的請求是異步發送的,因此瀏覽器可以繼續響應用戶輸入,同時在後臺等待服務器的響應。如果選擇同步操作,而且倘若服務器的響應要花幾秒才能到達,瀏覽器就會表現得很遲鈍,在等待期間不能響應用戶的輸入。這樣一來,瀏覽器好像被凍住一樣,無法響應用戶輸入,而異步做法可以避免這種情況,從而讓最終用戶有更好的體驗。儘管這種改善很細微,但確實很有意義。這樣用戶就能繼續工作,而且服務器會在後臺處理先前的請求。
圖2-4 第一個簡單的異步請求
與服務器通信而不打斷用戶的使用流程,這種能力使開發人員採用多種技術改善用戶體驗成爲可能。例如,假設有一個驗證用戶輸入的應用。用戶在輸入表單上填寫各個字段時,瀏覽器可以定期地向服務器發送表單值來進行驗證,此時並不打斷用戶,他還可以繼續填寫餘下的表單字段。如果某個驗證規則失敗,在表單真正發送到服務器進行處理之前,用戶就會立即得到通知,這就能大大節省用戶的時間,也能減輕服務器上的負載,因爲不必在表單提交不成功時完全重建表單的內容。
2.6.2  關於安全
文本框: 圖2-5 對於潛在的安全威脅,Internet Explorer和Firefox有不同的響應如果討論基於瀏覽器的技術時沒有提到安全,那麼討論就是不完整的。XMLHttpRequest對象要受制於瀏覽器的安全“沙箱”。XMLHttpRequest對象請求的所有資源都必須與調用腳本在同一個域內。這個安全限制使得XMLHttpRequest對象不能請求腳本所在域之外的資源
這個安全限制的強度因瀏覽器而異(見圖2-5)。IE會顯示一個警告,指出可能存在一個潛在的安全風險,但是用戶可以選擇是否繼續發出請求。Firefox則會斷然停止請求,並在JavaScript控制檯顯示一個錯誤消息。
Firefox確實提供了一些JavaScript技巧,使得XMLHttpRequest也可以請求外部URL的資源。不過,由於這些技術針對特定的瀏覽器,所以最好不要用,而且要避免使用XMLHttpRequest訪問外部URL。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章