對於許多Web 開發人員來說,只需要產生簡單的請求並接收簡單的回應即可;但是對於希望掌握Ajax 的開發人員來說,必須要全面理解HTTP 狀態碼、就緒狀態和XMLHttpRequest 物件。在本文中,Brett McLaughlin 將向您介紹各種狀態代碼,並展示瀏覽器如何對其進行處理,本文還給出了在Ajax 中使用的比較少見的HTTP 請求。
在本系列的上篇文章中,我們將詳細介紹XMLHttpRequest 對象,它是Ajax 應用程式的中心,負責處理伺服器端應用程式和腳本的請求,並處理從伺服器端元件返回的資料。由於所有的Ajax 應用程式都要使用XMLHttpRequest 對象,因此您可能會希望熟悉這個對象,從而能夠讓Ajax 執行得更好。
在本文中,我將在上一篇文章的基礎上重點介紹這個請求對象的3 個關鍵部分的內容:
·HTTP 就緒狀態·HTTP 狀態代碼·可以生成的請求類型
這三部分內容都是在構造一個請求時所要考慮的因素;但是介紹這些主題的內容太少了。然而,如果您不僅僅是想了解Ajax 程式設計的常識,而是希望了解更多內容,就需要熟悉就緒狀態、狀態代碼和請求本身的內容。當應用程式出現問題時—— 這種問題總是存在—— 那麼如果能夠正確理解就緒狀態、如何產生HEAD 請求或400 的狀態碼的確切含義,就可以在5 分鐘內調試出問題,而不是在各種挫折和困惑中度過5 個小時。
下面讓我們先來看看HTTP 就緒狀態。
深入了解HTTP 就緒狀態
您應該還記得在上一篇文章中XMLHttpRequest 物件有一個名為readyState 的屬性。這個屬性確保伺服器已經完成了一個請求,通常會使用一個回呼函數從伺服器中讀出資料來更新Web 表單或頁面的內容。清單1 給了一個簡單的例子(這也是本系列的上一篇文章中的一個例子- 請參閱參考資料)。
XMLHttpRequest 或XMLHttp:換名玫瑰
Microsoft™ 和Internet Explorer 使用了一個名為XMLHttp 的對象,而不是XMLHttpRequest 對象,而Mozilla、Opera、Safari 和大部分非Microsoft 瀏覽器都使用的是後者。為了簡單性起見,我將這兩個物件都簡單地稱為XMLHttpRequest。這既符合我們在Web 上看到的情況,也符合Microsoft 在Internet Explorer 7.0 中使用XMLHttpRequest 作為請求物件的意圖。 (有關這個問題的更多內容,請參閱第2 部分。)
清單1. 在回呼函數中處理伺服器的回應
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/n/g, "<br />");
} else
alert("status is " + request.status);
}
}
這顯然是就緒狀態最常見(也是最簡單)的用法。正如您從數字"4" 中可以看出的一樣,還有其他幾個就緒狀態(您在上一篇文章中也看到過這個清單—— 請參見參考資料):
·0:請求未初始化(還沒有呼叫open())。
·1:請求已經建立,但是還沒有發送(還沒有呼叫send())。
·2:請求已發送,正在處理中(通常現在可以從回應中獲取內容頭)。
·3:請求在處理中;通常回應中已有部分資料可用了,但是伺服器還沒有完成回應的產生。
·4:回應已完成;您可以取得並使用伺服器的回應了。
如果您希望不僅僅是了解Ajax 程式設計的基本知識,那麼就不但需要知道這些狀態,了解這些狀態是何時出現的,以及如何來使用這些狀態。首先,您需要學習在每種就緒狀態下可能碰到的是哪種請求狀態。不幸的是,這一點並不直觀,而且會涉及幾種特殊的情況。
隱密就緒狀態
第一種就緒狀態的特性是readyState 屬性為0(readyState == 0),表示未初始化狀態。一旦對請求物件呼叫open() 之後,這個屬性就被設定為1。由於您通常都是在一對請求進行初始化之後就立即呼叫open(),因此很少會看到readyState == 0 的狀態。另外,未初始化的就緒狀態在實際的應用程式中是沒有真正的用處的。
不過為了滿足我們的興趣,請參考清單2 的內容,其中顯示如何在readyState 被設定為0 時來取得這種就緒狀態。
清單2. 取得0 就緒狀態
function getSalesData() {
// Create a request object
createRequest();
alert("Ready state is: " + request.readyState);
// Setup (initialize) the request
var url = "/boards/servlet/UpdateBoardSales";
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
在這個簡單的範例中,getSalesData() 是Web 頁面呼叫來啟動請求(例如點擊一個按鈕時)所使用的函數。注意您必須在呼叫open()之前來查看就緒狀態。圖1 給出了運行這個應用程式的結果。
圖1. 就緒狀態0
顯然,這並不能為您帶來多少好處;需要確保尚未呼叫open() 函數的情況很少。在大部分Ajax 程式設計的真實情況中,這種就緒狀態的唯一用法就是使用相同的XMLHttpRequest 物件在多個函數之間產生多個請求。在這種(不常見的)情況中,您可能會在產生新請求之前希望確保請求物件是處於未初始化狀態(readyState == 0)。這實際上是要確保另外一個函數沒有同時使用這個物件。
查看正在處理的請求的就緒狀態
除了0 就緒狀態之外,請求對象還需要依次經歷典型的請求和回應的其他幾種就緒狀態,最後才以就緒狀態4 的形式結束。這就是為什麼您在大部分回調函數中都可以看到if (request.readyState == 4) 這行程式碼;它確保伺服器已經完成對請求的處理,現在可以安全地更新Web 頁面或根據從伺服器返回來的數據來進行操作了。
要查看這種狀態發生的過程非常簡單。如果就緒狀態為4,我們不僅要執行回呼函數中的程式碼,還要在每次呼叫回呼函數時都輸出就緒狀態。 清單3 給了一個實現這種功能的例子。
當0 等於4 時
在多個JavaScript 函數都使用相同的請求物件時,您需要檢查就緒狀態0 來確保這個請求物件沒有正在使用,這種機制會產生問題。由於readyState == 4 表示已完成的請求,因此您經常會發現那些目前沒在使用的處於就緒狀態的請求對象仍然被設定成了4 —— 這是因為從伺服器返回的資料已經使用過了,但是從它們被設定為就緒狀態之後就沒有進行任何變更。有一個函數abort() 會重新設定請求對象,但是這個函數卻不是真正為了這個目的而使用的。如果您必須使用多個函數,最好是為每個函數建立並使用一個函數,而不是在多個函數之間共用相同的物件。
清單3. 查看就緒狀態
function updatePage() {
// Output the current ready state
alert("updatePage() called with ready state of " + request.readyState);
}
如果您不確定如何執行這個函數,就需要建立一個函數,然後在Web 頁面中呼叫這個函數,並讓它向伺服器端的元件發送請求(例如清單2 給出的函數,或本系列文章的第1 部分和第2 部分中給出的例子)。確保在建立請求時,將回呼函數設為updatePage();要實現此設置,可以將請求物件的onreadystatechange 屬性設為updatePage()。
這段程式碼就是onreadystatechange 意義的一個確切展示- 每次請求的就緒狀態改變時,就呼叫updatePage(),然後我們就可以看到一個警告了。圖2 給出了一個呼叫這個函數的例子,其中就緒狀態為1。
圖2. 就緒狀態1
您可以自己嘗試運行這段程式碼。將其放入Web 頁面中,然後啟動事件處理程序(按一下按鈕,在網域之間按tab 鍵切換焦點,或使用設定的任何方法來觸發請求)。這個回呼函數會運行多次— 每次就緒狀態都會改變— 您可以看到每個就緒狀態的警告。這是追蹤請求所經歷的各個階段的最佳方法。
瀏覽器的不一致
在對這個過程有一個基本的了解之後,請試著從幾個不同的瀏覽器中訪問您的頁面。您應該會注意到各個瀏覽器如何處理這些就緒狀態並不一致。例如,在Firefox 1.5 中,您會看到以下就緒狀態:
·1
·2
·3
·4
這並不奇怪,因為每個請求狀態都在這裡表示出來了。然而,如果您使用Safari 來訪問相同的應用程序,就應該看到—— 或看不到—— 一些有趣的事情。下面是在Safari 2.0.1 中看到的狀態:
·2
·3
·4
Safari 實際上把第一個就緒狀態給丟棄了,也並沒有什麼明顯的原因說明為什麼要這樣做;不過這就是Safari 的工作方式。這也說明了一個重要的問題:儘管在使用伺服器上的資料之前確保請求的狀態為4 是一個好主意,但是依賴於每個過渡期就緒狀態編寫的程式碼的確會在不同的瀏覽器上得到不同的結果。
例如,使用Opera 8.5 時,所顯示的就緒狀態情況就更糟了:
·3
·4
最後,Internet Explorer 會顯示如下狀態:
·1
·2
·3
·4
如果您碰到請求方面的問題,這就是用來發現問題的首要之處。最好的方式是在Internet Explorer 和Firefox 都進行測試- 您會看到所有這4 種狀態,並可以檢查請求的每個狀態所處的情況。
接下來我們再來看看響應端的狀況。
顯微鏡下的回應資料
一旦我們理解在請求過程中發生的各個就緒狀態之後,接下來就可以來看一下XMLHttpRequest 物件的另一個面向了— responseText 屬性。回想一下在上一篇文章中我們介紹過的內容,就可以知道這個屬性是用來從伺服器上取得資料。一旦伺服器完成對請求的處理之後,就可以將回應請求資料所需的任何資料放到請求的responseText 中了。然後回呼函數就可以使用這些數據,如清單1 和清單4 所示。
清單4. 使用伺服器上回傳的回應
function updatePage() {
if (request.readyState == 4) {
var newTotal = request.responseText;
var totalSoldEl = document.getElementById("total-sold");
var netProfitEl = document.getElementById("net-profit");
replaceText(totalSoldEl, newTotal);
/* 圖out the new net profit */
var boardCostEl = document.getElementById("board-cost");
var boardCost = getText(boardCostEl);
var manCostEl = document.getElementById("man-cost");
var manCost = getText(manCostEl);
var profitPerBoard = boardCost - manCost;
var netProfit = profitPerBoard * newTotal;
/* Update the net profit on the sales form */
netProfit = Math.round(netProfit * 100) / 100;
replaceText(netProfitEl, netProfit);
}
清單1 相當簡單;清單4 稍微有點複雜,但是它們在開始時都要檢查就緒狀態,並取得responseText 屬性的值。
查看請求的回應文字
與就緒狀態類似,responseText 屬性的值在整個請求的生命週期中也會改變。要查看這種變化,請使用如清單5 所示的程式碼來測試請求的回應文本,以及它們的就緒狀態。
清單5. 測試responseText 屬性
function updatePage() {
// Output the current ready state
alert("updatePage() called with ready state of " + request.readyState +
" and a response text of '" + request.responseText + "'");
}
現在在瀏覽器中開啟Web 應用程序,並啟動您的請求。要更清楚地看到這段程式碼的效果,請使用Firefox 或Internet Explorer,因為這兩個瀏覽器都可以報告出請求過程中所有可能的就緒狀態。例如在就緒狀態2 中,就沒有定義responseText (請參考圖3);如果JavaScript 控制台也已經開啟了,您就會看到一個錯誤。
圖3. 就緒狀態為2 的回應文字
不過在就緒狀態3 中,伺服器已經在responseText 屬性中放上了一個值,至少在這個範例中是如此(請參見圖4)。
圖4. 就緒狀態為3 的回應文字
您會看到就緒狀態為3 的回應在每個腳本、每個伺服器甚至每個瀏覽器上都是不一樣的。不過,這在調試應用程式中依然是非常有用的。
取得安全資料
所有的文件和規範都強調,只有在就緒狀態為4 時資料才可以安全使用。相信我,當就緒狀態為3 時,您很少能找到無法從responseText 屬性取得資料的情況。然而,在應用程式中將自己的邏輯依賴就緒狀態3 可不是什麼好主意—— 一旦您編寫了依賴就緒狀態3 的完整數據的的代碼,幾乎就要自己來負責當時的數據不完整問題了。
比較好的做法是向使用者提供一些回饋,說明在處於就緒狀態3 時,很快就會有回應了。儘管使用alert() 之類的函數顯然不是什麼好主意—— 使用Ajax 然後使用一個警告對話框來阻塞用戶顯然是錯誤的—— 不過您可以在就緒狀態發生變化時更新表單或頁面中的域。例如,對於就緒狀態1 來說要將進度指示器的寬度設為25%,對於就緒狀態2 來說要將進度指示器的寬度設為50%,對於就緒狀態3 來說要將進度指示器的寬度設定為75%,就緒狀態為4 時將進度指示器的寬度設定為100%(完成)。
當然,正如您已經看到的一樣,這種方法非常聰明,但它是依賴瀏覽器的。在Opera 上,您永遠不會看到前兩個就緒狀態,而在Safari 上則沒有第一個(1)。由於這個原因,我將這段程式碼留作練習,而沒有在本文中包括進來。
現在應該來看一下狀態代碼了。
深入了解
HTTP 狀態代碼有了就緒狀態和您在Ajax 編程技術中學習到的伺服器的回應,您就可以為Ajax 應用程式添加另外一級複雜性了—— 這要使用HTTP 狀態代碼。這些程式碼對於Ajax 來說並沒有什麼新鮮。從Web 出現以來,它們就已經存在了。在Web 瀏覽器中您可能已經看過幾個狀態代碼:
·401:未經授權·403:禁止·404:沒找到
您可以找到更多的狀態代碼(完整清單請參考參考資料)。要為Ajax 應用程式另外添加一層控制和回應(以及更健壯的錯誤處理)機制,您需要適當地查看請求和回應中的狀態代碼。
200:一切正常
在許多Ajax 應用程式中,您將看到一個回調函數,它負責檢查就緒狀態,然後繼續利用從伺服器回應中返回的數據,如清單6 所示。
清單6. 忽略狀態碼的回呼函數
function updatePage() {
if (request.readyState == 4) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/n/g, "<br />");
}
}
這對Ajax 程式來說證明是一種短視而錯誤的方法。如果腳本需要認證,而請求卻沒有提供有效的證書,那麼伺服器就會傳回諸如403 或401 之類的錯誤代碼。然而,由於伺服器對請求進行了應答,因此就緒狀態就設定為4(即使應答並不是請求所期望的也是如此)。最終,使用者沒有獲得有效數據,當JavaScript 試圖使用不存在的伺服器資料時就可能會出現嚴重的錯誤。
它花費了最小的努力來確保伺服器不僅完成了一個請求,而且還返回了一個「一切良好」 的狀態代碼。這個程式碼是"200",它是透過XMLHttpRequest 物件的status 屬性來報告的。為了確保伺服器不但完成了一個請求,而且還報告了一個OK 狀態,請在您的回呼函數中新增另一個檢查功能,如清單7 所示。
清單7. 檢查有效狀態代碼
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/n/g, "<br />");
} else
alert("status is " + request.status);
}
}
透過新增這幾行程式碼,您就可以確認是否有問題,使用者會看到一個有用的錯誤訊息,而不僅僅是看到一個由斷章取義的資料所構成的頁面,而沒有任何解釋。
重定向和重新路由
在深入介紹有關錯誤的內容之前,我們有必要來討論一下有關一個在使用Ajax 時並不需要關心的問題— 重定向。在HTTP 狀態代碼中,這是300 系列的狀態代碼,包括:
·301:永久移動·302:找到(請求重新定向到另一個URL/URI 上)
·305:使用代理(請求必須使用一個代理來存取所請求的資源)
Ajax 程式設計師可能並不太關心有關重定向的問題,這是由於兩方面的原因:
·首先,Ajax 應用程式通常都是為一個特定的伺服器端腳本、servlet 或應用程式而編寫的。對於那些您看不到就消失了的元件來說,Ajax 程式設計師就不太清楚了。因此有時您會知道資源已經移動了(因為您移動了它,或者透過某種手段移動了它),接下來要修改請求中的URL,並且不會再碰到這種結果了。
更重要的一個原因是:Ajax 應用程式和請求都是封裝在沙盒中的。這意味著提供產生Ajax 請求的Web 頁面的網域必須是對這些請求進行回應的網域。因此ebay.com 所提供的Web 頁面就不能對一個在amazon.com 上運行的腳本產生一個Ajax 風格的請求;在ibm.com 上的Ajax 應用程式也無法對在netbeans.org 上運行的servlets 發出請求。
·結果是您的請求無法重新導向到其他伺服器上,而不會產生安全性錯誤。在這些情況中,您根本就不會得到狀態代碼。通常在偵錯控制台中都會產生一個JavaScript 錯誤。因此,在對狀態程式碼進行充分的考慮之後,您就可以完全忽略重定向程式碼的問題了。
結果是您的請求無法重定向到其他伺服器上,而不會產生安全性錯誤。在這些情況中,您根本就不會得到狀態代碼。通常在偵錯控制台中都會產生一個JavaScript 錯誤。因此,在對狀態程式碼進行充分的考慮之後,您就可以完全忽略重定向程式碼的問題了。
錯誤
一旦接收到狀態代碼200 並且意識到可以很大程度上忽略300 系列的狀態代碼之後,所需要擔心的唯一一組代碼就是400 系列的代碼了,這說明了不同類型的錯誤。回頭再來看一下清單7,並注意在對錯誤進行處理時,只將少數常見的錯誤訊息輸出給用戶了。儘管這是朝著正確方向前進的一步,但是要告訴從事應用程式開發的使用者和程式設計師究竟發生了什麼問題,這些訊息仍然是沒有太大用處的。
首先,我們要新增對找不到的頁面的支援。實際上這在大部分產品系統中都不應該出現,但是在測試腳本位置發生變化或程式設計師輸入了錯誤的URL 時,這種情況並不罕見。如果您可以自然地報告404 錯誤,您可以為那些困擾不堪的使用者和程式設計師提供更多幫助。例如,如果伺服器上的腳本被刪除了,我們就可以使用清單7 中的程式碼,這樣使用者就會看到一個如圖5 所示的非描述性錯誤。
邊界情況和困難情況
看到現在,一些新手程式設計師就可能會這究竟是要討論什麼內容。有一點事實大家需要知道:只有不到5% 的Ajax 請求需要使用諸如2、3 之類的就緒狀態和諸如403 之類的狀態代碼(實際上,這個比率可能更接近於1% 甚至更少) 。這些情況非常重要,稱為邊界情況(edge case) —— 它們只會在一些非常特殊的情況下發生,其中遇到的都是最奇特的問題。雖然這些情況並不普遍,但是這些邊界情況卻佔據了大部分用戶所碰到的問題的80%!
對於典型的用戶來說,應用程式100 次都是正常工作的這個事實通常都會被忘記,然而應用程式只要一次出錯就會被他們清楚地記住。如果您可以很好地處理邊界情況(或困難情況),您可以為再次造訪網站的使用者提供滿意的回報。
圖5. 常見錯誤處理
使用者無法判斷問題究竟是認證問題、沒找到腳本(這裡就是這種情況)、使用者錯誤或程式碼中有些地方產生了問題。加入一些簡單的程式碼可以讓這個錯誤更具體。請參考清單8,它負責處理沒找到的腳本或認證發生錯誤的情況,在出現這些錯誤時都會給出具體的訊息。
清單8. 檢查有效狀態代碼
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/n/g, "<br />");
} else if (request.status == 404) {
alert ("Requested URL is not found.");
} else if (request.status == 403) {
alert("Access denied.");
} else
alert("status is " + request.status);
}
}
雖然這仍然相當簡單,但是它的確多提供了一些有用的信息。圖6 給出了與圖5 相同的錯誤,但是這次錯誤處理代碼向使用者或程式設計師更好地說明了究竟發生了什麼。
圖6. 特殊錯誤處理
在我們自己的應用程式中,可以考慮在發生認證失敗的情況時清除使用者名稱和密碼,並在螢幕上添加錯誤訊息。我們可以使用類似的方法來更好地處理找不到腳本或其他400 類型的錯誤(例如405 表示不允許使用諸如發送HEAD 請求之類不可接受的請求方法,而407 則表示需要進行代理認證)。然而不管採用哪種選擇,都需要從伺服器上傳回的狀態代碼開始入手處理。
其他請求類型
如果您真希望控制XMLHttpRequest 對象,可以考慮最後實作此功能- 將HEAD 請求新增到指令中。在前兩篇文章中,我們已經介紹瞭如何產生GET 請求;在馬上就要發表的一篇文章中,您會學習有關使用POST 請求將資料傳送到伺服器上的知識。不過本著增強錯誤處理和資訊蒐集的精神,您應該學習如何產生HEAD 請求。
產生請求
實際上產生HEAD 請求非常簡單;您可以使用"HEAD"(而不是"GET" 或"POST")作為第一個參數來呼叫open() 方法,如清單9 所示。
清單9. 使用Ajax 產生一個HEAD 請求
function getSalesData() {
createRequest();
var url = "/boards/servlet/UpdateBoardSales";
request.open("HEAD", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
當您這樣產生一個HEAD 請求時,伺服器並不會像對GET 或POST 請求一樣回傳一個真正的回應。相反,伺服器只會傳回資源的頭(header),這包括回應中內容最後修改的時間、請求資源是否存在和許多其他有用資訊。您可以在伺服器處理並返回資源之前使用這些資訊來了解有關資源的資訊。
對於這種請求您可以做的最簡單的事情就是簡單地輸出所有的回應頭的內容。這可以讓您了解透過HEAD 請求可以使用什麼。清單10 提供了一個簡單的回呼函數,用來輸出從HEAD 請求中獲得的回應頭的內容。
清單10. 輸出從HEAD 請求中獲得的回應頭的內容
function updatePage() {
if (request.readyState == 4) {
alert(request.getAllResponseHeaders());
}
}
請參閱圖7,其中顯示了從一個向伺服器發出的HEAD 請求的簡單Ajax 應用程式傳回的回應頭。
您可以單獨使用這些頭(從伺服器類型到內容類型)在Ajax 應用程式中提供其他資訊或功能。
檢查URL
您已經看到了當URL 不存在時應該如何檢查404 錯誤。如果這變成一個常見的問題—— 可能是缺少了一個特定的腳本或servlet —— 那麼您可能會希望在產生完整的GET 或POST 請求之前來檢查這個URL。要實現這種功能,產生一個HEAD 請求,然後在回呼函數中檢查404 錯誤;清單11 給出了一個簡單的回呼函數。
清單11. 檢查某個URL 是否存在
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
alert("URL exists");
} else if (request.status == 404) {
alert("URL does not exist.");
} else {
alert("Status is: " + request.status);
}
}
}
誠實地說,這段程式碼的價值並不太大。伺服器必須對請求進行回應,並建構一個回應來填充內容長度的回應頭,因此並不能節省任何處理時間。另外,這花費的時間與產生請求並使用HEAD 請求來查看URL 是否存在所需的時間一樣多,因為它要產生使用GET 或POST 的請求,而不僅僅是如清單7 所示一樣來處理錯誤代碼。不過,有時確切地了解目前什麼可用也是非常有用的;您永遠不會知道何時創造力就會迸發或何時需要HEAD 請求!
有用的HEAD 請求
您會發現HEAD 請求非常有用的一個領域是用來查看內容的長度或內容的類型。這樣可以確定是否需要發回大量數據來處理請求,和伺服器是否試圖返回二進位數據,而不是HTML、文字或XML(在JavaScript 中,這3 種類型的數據都比二進位數據更容易處理)。
在這些情況中,您只使用了適當的頭名,並將其傳遞給XMLHttpRequest 物件的getResponseHeader() 方法。因此要取得回應的長度,只需要呼叫request.getResponseHeader("Content-Length");。若要取得內容類型,請使用request.getResponseHeader("Content-Type");。
在許多應用程式中,產生HEAD 請求並沒有增加任何功能,甚至可能會導致請求速度變慢(透過強制產生一個HEAD 請求來獲取有關回應的數據,然後在使用一個GET 或POST 請求來真正獲取回應) 。然而,在出現您不確定有關腳本或伺服器端元件的情況時,使用HEAD 請求可以獲得一些基本的數據,而不需要對回應資料真正進行處理,也不需要大量的頻寬來發送回應。
結語
對於許多Ajax 和Web 程式設計師來說,本文介紹的內容似乎太進階了。產生HEAD 請求的價值是什麼呢?到底在什麼情況下需要在JavaScript 中明確地處理重定向狀態碼呢?這些都是很好的問題;對於簡單的應用程式來說,答案是這些高級技術的價值並不是非常大。
然而,Web 不再是只需實現簡單應用程式的地方了;用戶已經變得更加高級,客戶期望能夠獲得更好的穩定性、更高級的錯誤報告,如果應用程式有1% 的時間停機,那麼經理就可能會因此而被解僱。
因此您的工作就不能僅限於簡單的應用程式了,而是需要更深入地理解XMLHttpRequest。
·如果您可以考慮各種就緒狀態—— 並且了解這些就緒狀態在不同瀏覽器之間的差異—— 就可以快速調試應用程式了。您甚至可以基於就緒狀態而開發一些創意的功能,並向使用者和客戶回報請求的狀態。
·如果您要對狀態代碼進行控制,您可以設定應用程式來處理腳本錯誤、非預期的回應以及邊緣情況。結果是應用程式在所有的時間都可以正常工作,而不僅僅是只能在一切都正常的情況下運作。
·增加這種產生HEAD 請求的能力,檢查某個URL 是否存在,以及確認某個文件是否被修改過,這樣就可以確保用戶可以獲得有效的頁面,用戶所看到的資訊都是最新的,(最重要的是)讓他們驚訝這個應用程式是如何健壯和通用。
本文的目的並非是要讓您的應用程式顯得十分華麗,而是幫助您去除黃色聚光燈後重點昭顯文字的美麗,或者外觀更像桌面一樣。儘管這些都是Ajax 的功能(在後續幾篇文章中就會介紹),不過它們卻像是蛋糕表面的一層奶油。如果您可以使用Ajax 來建立一個堅實的基礎,讓應用程式可以很好地處理錯誤和問題,使用者就會返回您的網站和應用程式。在接下來的文章中,我們將加入這種直覺的技巧,這會讓客戶興奮得發抖。 (認真地說,您一定不希望錯過下一篇文章!)