作者:Brett McLaughlin 來(lái)源:developerWorks 中國
閱讀 62 人次 , 2006-4-2 23:25:00
對于很多 web 開(kāi)發(fā)人員來(lái)說(shuō),只需要生成簡(jiǎn)單的請求并接收簡(jiǎn)單的響應即可;但是對于希望掌握 ajax 的開(kāi)發(fā)人員來(lái)說(shuō),必須要全面理解 http 狀態(tài)代碼、就緒狀態(tài)和 xmlhttprequest 對象。
在本文中,將重點(diǎn)介紹這個(gè)請求對象的 3 個(gè)關(guān)鍵部分的內容:
http 就緒狀態(tài) http 狀態(tài)代碼 可以生成的請求類(lèi)型
這三部分內容都是在構造一個(gè)請求時(shí)所要考慮的因素;但是介紹這些主題的內容太少了。然而,如果您不僅僅是想了解 ajax 編程的常識,而是希望了解更多內容,就需要熟悉就緒狀態(tài)、狀態(tài)代碼和請求本身的內容。當應用程序出現問(wèn)題時(shí) —— 這種問(wèn)題總是存在 —— 那么如果能夠正確理解就緒狀態(tài)、如何生成一個(gè) head 請求或者 400 的狀態(tài)代碼的確切含義,就可以在 5 分鐘內調試出問(wèn)題,而不是在各種挫折和困惑中度過(guò) 5 個(gè)小時(shí)。
下面讓我們首先來(lái)看一下 http 就緒狀態(tài)。
深入了解 http 就緒狀態(tài)
您應該還記得在上一篇文章中 xmlhttprequest 對象有一個(gè)名為 readystate 的屬性。這個(gè)屬性確保服務(wù)器已經(jīng)完成了一個(gè)請求,通常會(huì )使用一個(gè)回調函數從服務(wù)器中讀出數據來(lái)更新 web 表單或頁(yè)面的內容。清單 1 給出了一個(gè)簡(jiǎn)單的例子。
清單 1. 在回調函數中處理服務(wù)器的響應
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, "
");
} else
alert("status is " + request.status);
}
}
這顯然是就緒狀態(tài)最常見(jiàn)(也是最簡(jiǎn)單)的用法。正如您從數字 "4" 中可以看出的一樣,還有其他幾個(gè)就緒狀態(tài):
0:請求未初始化(還沒(méi)有調用 open())。 1:請求已經(jīng)建立,但是還沒(méi)有發(fā)送(還沒(méi)有調用 send())。 2:請求已發(fā)送,正在處理中(通?,F在可以從響應中獲取內容頭)。 3:請求在處理中;通常響應中已有部分數據可用了,但是服務(wù)器還沒(méi)有完成響應的生成。 4:響應已完成;您可以獲取并使用服務(wù)器的響應了。
如果您希望不僅僅是了解 ajax 編程的基本知識,那么就不但需要知道這些狀態(tài),了解這些狀態(tài)是何時(shí)出現的,以及如何來(lái)使用這些狀態(tài)。首先,您需要學(xué)習在每種就緒狀態(tài)下可能碰到的是哪種請求狀態(tài)。不幸的是,這一點(diǎn)并不直觀(guān),而且會(huì )涉及幾種特殊的情況。
隱秘就緒狀態(tài)
第一種就緒狀態(tài)的特點(diǎn)是 readystate 屬性為 0(readystate == 0),表示未初始化狀態(tài)。一旦對請求對象調用 open() 之后,這個(gè)屬性就被設置為 1。由于您通常都是在一對請求進(jìn)行初始化之后就立即調用 open(),因此很少會(huì )看到 readystate == 0 的狀態(tài)。另外,未初始化的就緒狀態(tài)在實(shí)際的應用程序中是沒(méi)有真正的用處的。
不過(guò)為了滿(mǎn)足我們的興趣,請參見(jiàn) 清單 2 的內容,其中顯示了如何在 readystate 被設置為 0 時(shí)來(lái)獲取這種就緒狀態(tài)。
清單 2. 獲取 0 就緒狀態(tài)
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);
}
在這個(gè)簡(jiǎn)單的例子中,getsalesdata() 是 web 頁(yè)面調用來(lái)啟動(dòng)請求(例如點(diǎn)擊一個(gè)按鈕時(shí))所使用的函數。注意您必須在調用 open()之前 來(lái)查看就緒狀態(tài)。圖 1 給出了運行這個(gè)應用程序的結果。
圖 1. 就緒狀態(tài) 0
顯然,這并不能為您帶來(lái)多少好處;需要確保 尚未 調用 open() 函數的情況很少。在大部分 ajax 編程的真實(shí)情況中,這種就緒狀態(tài)的唯一用法就是使用相同的 xmlhttprequest 對象在多個(gè)函數之間生成多個(gè)請求。在這種(不常見(jiàn)的)情況中,您可能會(huì )在生成新請求之前希望確保請求對象是處于未初始化狀態(tài)(readystate == 0)。這實(shí)際上是要確保另外一個(gè)函數沒(méi)有同時(shí)使用這個(gè)對象。
顯微鏡下的響應數據
一旦我們理解在請求過(guò)程中發(fā)生的各個(gè)就緒狀態(tài)之后,接下來(lái)就可以來(lái)看一下 xmlhttprequest 對象的另外一個(gè)方面了 —— responsetext 屬性?;叵胍幌略谏弦黄恼轮形覀兘榻B過(guò)的內容,就可以知道這個(gè)屬性用來(lái)從服務(wù)器上獲取數據。一旦服務(wù)器完成對請求的處理之后,就可以將響應請求數據所需要的任何數據放到請求的 responsetext 中了。然后回調函數就可以使用這些數據,如 清單 1 和 清單 4 所示。
清單 4. 使用服務(wù)器上返回的響應
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 相當簡(jiǎn)單;清單 4 稍微有點(diǎn)復雜,但是它們在開(kāi)始時(shí)都要檢查就緒狀態(tài),并獲取 responsetext 屬性的值。
查看請求的響應文本
與就緒狀態(tài)類(lèi)似,responsetext 屬性的值在整個(gè)請求的生命周期中也會(huì )發(fā)生變化。要查看這種變化,請使用如 清單 5 所示的代碼來(lái)測試請求的響應文本,以及它們的就緒狀態(tài)。
清單 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 + "‘");
}
現在在瀏覽器中打開(kāi) web 應用程序,并激活您的請求。要更好地看到這段代碼的效果,請使用 firefox 或 internet explorer,因為這兩個(gè)瀏覽器都可以報告出請求過(guò)程中所有可能的就緒狀態(tài)。例如在就緒狀態(tài) 2 中,就沒(méi)有定義 responsetext (請參見(jiàn) 圖 3);如果 javascript 控制臺也已經(jīng)打開(kāi)了,您就會(huì )看到一個(gè)錯誤。
圖 3. 就緒狀態(tài)為 2 的響應文本
不過(guò)在就緒狀態(tài) 3 中,服務(wù)器已經(jīng)在 responsetext 屬性中放上了一個(gè)值,至少在這個(gè)例子中是這樣(請參見(jiàn) 圖 4)。
圖 4. 就緒狀態(tài)為 3 的響應文本
您會(huì )看到就緒狀態(tài)為 3 的響應在每個(gè)腳本、每個(gè)服務(wù)器甚至每個(gè)瀏覽器上都是不一樣的。不過(guò),這在調試應用程序中依然是非常有用的。
獲取安全數據
所有的文檔和規范都強調,只有在就緒狀態(tài)為 4 時(shí)數據才可以安全使用。相信我,當就緒狀態(tài)為 3 時(shí),您很少能找到無(wú)法從 responsetext 屬性獲取數據的情況。然而,在應用程序中將自己的邏輯依賴(lài)于就緒狀態(tài) 3 可不是什么好主意 —— 一旦您編寫(xiě)了依賴(lài)于就緒狀態(tài) 3 的完整數據的的代碼,幾乎就要自己來(lái)負責當時(shí)的數據不完整問(wèn)題了。
比較好的做法是向用戶(hù)提供一些反饋,說(shuō)明在處于就緒狀態(tài) 3 時(shí),很快就會(huì )有響應了。盡管使用 alert() 之類(lèi)的函數顯然不是什么好主意 —— 使用 ajax 然后使用一個(gè)警告對話(huà)框來(lái)阻塞用戶(hù)顯然是錯誤的 —— 不過(guò)您可以在就緒狀態(tài)發(fā)生變化時(shí)更新表單或頁(yè)面中的域。例如,對于就緒狀態(tài) 1 來(lái)說(shuō)要將進(jìn)度指示器的寬度設置為 25%,對于就緒狀態(tài) 2 來(lái)說(shuō)要將進(jìn)度指示器的寬度設置為 50%,對于就緒狀態(tài) 3 來(lái)說(shuō)要將進(jìn)度指示器的寬度設置為 75%,當就緒狀態(tài)為 4 時(shí)將進(jìn)度指示器的寬度設置為 100%(完成)。
當然,正如您已經(jīng)看到的一樣,這種方法非常聰明,但它是依賴(lài)于瀏覽器的。在 opera 上,您永遠都不會(huì )看到前兩個(gè)就緒狀態(tài),而在 safari 上則沒(méi)有第一個(gè)(1)。由于這個(gè)原因,我將這段代碼留作練習,而沒(méi)有在本文中包括進(jìn)來(lái)。
現在應該來(lái)看一下?tīng)顟B(tài)代碼了。
深入了解 http 狀態(tài)代碼
有了就緒狀態(tài)和您在 ajax 編程技術(shù)中學(xué)習到的服務(wù)器的響應,您就可以為 ajax 應用程序添加另外一級復雜性了 —— 這要使用 http 狀態(tài)代碼。這些代碼對于 ajax 來(lái)說(shuō)并沒(méi)有什么新鮮。從 web 出現以來(lái),它們就已經(jīng)存在了。在 web 瀏覽器中您可能已經(jīng)看到過(guò)幾個(gè)狀態(tài)代碼:
401:未經(jīng)授權 403:禁止 404:沒(méi)找到
您可以找到更多的狀態(tài)代碼(完整清單請參見(jiàn) 參考資料)。要為 ajax 應用程序另外添加一層控制和響應(以及更為健壯的錯誤處理)機制,您需要適當地查看請求和響應中的狀態(tài)代碼。
200:一切正常
在很多 ajax 應用程序中,您將看到一個(gè)回調函數,它負責檢查就緒狀態(tài),然后繼續利用從服務(wù)器響應中返回的數據,如 清單 6 所示。
清單 6. 忽略狀態(tài)代碼的回調函數
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, "
");
}
}
這對于 ajax 編程來(lái)說(shuō)證明是一種短視而錯誤的方法。如果腳本需要認證,而請求卻沒(méi)有提供有效的證書(shū),那么服務(wù)器就會(huì )返回諸如 403 或 401 之類(lèi)的錯誤代碼。然而,由于服務(wù)器對請求進(jìn)行了應答,因此就緒狀態(tài)就被設置為 4(即使應答并不是請求所期望的也是如此)。最終,用戶(hù)沒(méi)有獲得有效數據,當 javascript 試圖使用不存在的服務(wù)器數據時(shí)就可能會(huì )出現嚴重的錯誤。
它花費了最小的努力來(lái)確保服務(wù)器不但完成了一個(gè)請求,而且還返回了一個(gè) “一切良好” 的狀態(tài)代碼。這個(gè)代碼是 "200",它是通過(guò) xmlhttprequest 對象的 status 屬性來(lái)報告的。為了確保服務(wù)器不但完成了一個(gè)請求,而且還報告了一個(gè) ok 狀態(tài),請在您的回調函數中添加另外一個(gè)檢查功能,如 清單 7 所示。
清單 7. 檢查有效狀態(tài)代碼
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, "
");
} else
alert("status is " + request.status);
}
}
通過(guò)添加這幾行代碼,您就可以確認是否存在問(wèn)題,用戶(hù)會(huì )看到一個(gè)有用的錯誤消息,而不僅僅是看到一個(gè)由斷章取義的數據所構成的頁(yè)面,而沒(méi)有任何解釋。
重定向和重新路由
在深入介紹有關(guān)錯誤的內容之前,我們有必要來(lái)討論一下有關(guān)一個(gè)在使用 ajax 時(shí) 并不需要 關(guān)心的問(wèn)題 —— 重定向。在 http 狀態(tài)代碼中,這是 300 系列的狀態(tài)代碼,包括:
301:永久移動(dòng) 302:找到(請求被重新定向到另外一個(gè) url/uri 上) 305:使用代理(請求必須使用一個(gè)代理來(lái)訪(fǎng)問(wèn)所請求的資源)
ajax 程序員可能并不太關(guān)心有關(guān)重定向的問(wèn)題,這是由于兩方面的原因:
首先,ajax 應用程序通常都是為一個(gè)特定的服務(wù)器端腳本、servlet 或應用程序而編寫(xiě)的。對于那些您看不到就消失了的組件來(lái)說(shuō),ajax 程序員就不太清楚了。因此有時(shí)您會(huì )知道資源已經(jīng)移動(dòng)了(因為您移動(dòng)了它,或者通過(guò)某種手段移動(dòng)了它),接下來(lái)要修改請求中的 url,并且不會(huì )再碰到這種結果了。 更為重要的一個(gè)原因是:ajax 應用程序和請求都是封裝在沙盒中的。這就意味著(zhù)提供生成 ajax 請求的 web 頁(yè)面的域必須是對這些請求進(jìn)行響應的域。因此 ebay.com 所提供的 web 頁(yè)面就不能對一個(gè)在 amazon.com 上運行的腳本生成一個(gè) ajax 風(fēng)格的請求;在 ibm.com 上的 ajax 應用程序也無(wú)法對在 netbeans.org 上運行的 servlets 發(fā)出請求。
結果是您的請求無(wú)法重定向到其他服務(wù)器上,而不會(huì )產(chǎn)生安全性錯誤。在這些情況中,您根本就不會(huì )得到狀態(tài)代碼。通常在調試控制臺中都會(huì )產(chǎn)生一個(gè) javascript 錯誤。因此,在對狀態(tài)代碼進(jìn)行充分的考慮之后,您就可以完全忽略重定向代碼的問(wèn)題了。
錯誤
一旦接收到狀態(tài)代碼 200 并且意識到可以很大程度上忽略 300 系列的狀態(tài)代碼之后,所需要擔心的唯一一組代碼就是 400 系列的代碼了,這說(shuō)明了不同類(lèi)型的錯誤?;仡^再來(lái)看一下 清單 7,并注意在對錯誤進(jìn)行處理時(shí),只將少數常見(jiàn)的錯誤消息輸出給用戶(hù)了。盡管這是朝正確方向前進(jìn)的一步,但是要告訴從事應用程序開(kāi)發(fā)的用戶(hù)和程序員究竟發(fā)生了什么問(wèn)題,這些消息仍然是沒(méi)有太大用處的。
首先,我們要添加對找不到的頁(yè)的支持。實(shí)際上這在大部分產(chǎn)品系統中都不應該出現,但是在測試腳本位置發(fā)生變化或程序員輸入了錯誤的 url 時(shí),這種情況并不罕見(jiàn)。如果您可以自然地報告 404 錯誤,就可以為那些困擾不堪的用戶(hù)和程序員提供更多幫助。例如,如果服務(wù)器上的一個(gè)腳本被刪除了,我們就可以使用 清單 7 中的代碼,這樣用戶(hù)就會(huì )看到一個(gè)如 圖 5 所示的非描述性錯誤。
圖 5. 常見(jiàn)錯誤處理
用戶(hù)無(wú)法判斷問(wèn)題究竟是認證問(wèn)題、沒(méi)找到腳本(此處就是這種情況)、用戶(hù)錯誤還是代碼中有些地方產(chǎn)生了問(wèn)題。添加一些簡(jiǎn)單的代碼可以讓這個(gè)錯誤更加具體。請參照 清單 8,它負責處理沒(méi)找到的腳本或認證發(fā)生錯誤的情況,在出現這些錯誤時(shí)都會(huì )給出具體的消息。
清單 8. 檢查有效狀態(tài)代碼
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, "
");
} 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);
}
}
雖然這依然相當簡(jiǎn)單,但是它的確多提供了一些有用的信息。圖 6 給出了與 圖 5 相同的錯誤,但是這一次錯誤處理代碼向用戶(hù)或程序員更好地說(shuō)明了究竟發(fā)生了什么。
圖 6. 特殊錯誤處理
在我們自己的應用程序中,可以考慮在發(fā)生認證失敗的情況時(shí)清除用戶(hù)名和密碼,并向屏幕上添加一條錯誤消息。我們可以使用類(lèi)似的方法來(lái)更好地處理找不到腳本或其他 400 類(lèi)型的錯誤(例如 405 表示不允許使用諸如發(fā)送 head 請求之類(lèi)不可接受的請求方法,而 407 則表示需要進(jìn)行代理認證)。然而不管采用哪種選擇,都需要從對服務(wù)器上返回的狀態(tài)代碼開(kāi)始入手進(jìn)行處理。
其他請求類(lèi)型
如果您真希望控制 xmlhttprequest 對象,可以考慮最后實(shí)現這種功能 —— 將 head 請求添加到指令中。在前兩篇文章中,我們已經(jīng)介紹了如何生成 get 請求;在馬上就要發(fā)表的一篇文章中,您會(huì )學(xué)習有關(guān)使用 post 請求將數據發(fā)送到服務(wù)器上的知識。不過(guò)本著(zhù)增強錯誤處理和信息搜集的精神,您應該學(xué)習如何生成 head 請求。
生成請求
實(shí)際上生成 head 請求非常簡(jiǎn)單;您可以使用 "head"(而不是 "get" 或 "post")作為第一個(gè)參數來(lái)調用 open() 方法,如 清單 9 所示。
清單 9. 使用 ajax 生成一個(gè) head 請求
function getsalesdata() {
createrequest();
var url = "/boards/servlet/updateboardsales";
request.open("head", url, true);
request.onreadystatechange = updatepage;
request.send(null);
}
當您這樣生成一個(gè) head 請求時(shí),服務(wù)器并不會(huì )像對 get 或 post 請求一樣返回一個(gè)真正的響應。相反,服務(wù)器只會(huì )返回資源的 頭(header),這包括響應中內容最后修改的時(shí)間、請求資源是否存在和很多其他有用信息。您可以在服務(wù)器處理并返回資源之前使用這些信息來(lái)了解有關(guān)資源的信息。
對于這種請求您可以做的最簡(jiǎn)單的事情就是簡(jiǎn)單地輸出所有的響應頭的內容。這可以讓您了解通過(guò) head 請求可以使用什么。清單 10 提供了一個(gè)簡(jiǎn)單的回調函數,用來(lái)輸出從 head 請求中獲得的響應頭的內容。
清單 10. 輸出從 head 請求中獲得的響應頭的內容
function updatepage() {
if (request.readystate == 4) {
alert(request.getallresponseheaders());
}
}
請參見(jiàn) 圖 7,其中顯示了從一個(gè)向服務(wù)器發(fā)出的 head 請求的簡(jiǎn)單 ajax 應用程序返回的響應頭。
圖 7. head 請求的響應頭
您可以單獨使用這些頭(從服務(wù)器類(lèi)型到內容類(lèi)型)在 ajax 應用程序中提供其他信息或功能。
檢查 url
您已經(jīng)看到了當 url 不存在時(shí)應該如何檢查 404 錯誤。如果這變成一個(gè)常見(jiàn)的問(wèn)題 —— 可能是缺少了一個(gè)特定的腳本或 servlet —— 那么您就可能會(huì )希望在生成完整的 get 或 post 請求之前來(lái)檢查這個(gè) url。要實(shí)現這種功能,生成一個(gè) head 請求,然后在回調函數中檢查 404 錯誤;清單 11 給出了一個(gè)簡(jiǎn)單的回調函數。
清單 11. 檢查某個(gè) 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);
}
}
}
誠實(shí)地說(shuō),這段代碼的價(jià)值并不太大。服務(wù)器必須對請求進(jìn)行響應,并構造一個(gè)響應來(lái)填充內容長(cháng)度的響應頭,因此并不能節省任何處理時(shí)間。另外,這花費的時(shí)間與生成請求并使用 head 請求來(lái)查看 url 是否存在所需要的時(shí)間一樣多,因為它要生成使用 get 或 post 的請求,而不僅僅是如 清單 7 所示一樣來(lái)處理錯誤代碼。不過(guò),有時(shí)確切地了解目前什么可用也是非常有用的;您永遠不會(huì )知道何時(shí)創(chuàng )造力就會(huì )迸發(fā)或者何時(shí)需要 head 請求!
有用的 head 請求
您會(huì )發(fā)現 head 請求非常有用的一個(gè)領(lǐng)域是用來(lái)查看內容的長(cháng)度或內容的類(lèi)型。這樣可以確定是否需要發(fā)回大量數據來(lái)處理請求,和服務(wù)器是否試圖返回二進(jìn)制數據,而不是 html、文本或 xml(在 javascript 中,這 3 種類(lèi)型的數據都比二進(jìn)制數據更容易處理)。
在這些情況中,您只使用了適當的頭名,并將其傳遞給 xmlhttprequest 對象的 getresponseheader() 方法。因此要獲取響應的長(cháng)度,只需要調用 request.getresponseheader("content-length");。要獲取內容類(lèi)型,請使用 request.getresponseheader("content-type");。
在很多應用程序中,生成 head 請求并沒(méi)有增加任何功能,甚至可能會(huì )導致請求速度變慢(通過(guò)強制生成一個(gè) head 請求來(lái)獲取有關(guān)響應的數據,然后在使用一個(gè) get 或 post 請求來(lái)真正獲取響應)。然而,在出現您不確定有關(guān)腳本或服務(wù)器端組件的情況時(shí),使用 head 請求可以獲取一些基本的數據,而不需要對響應數據真正進(jìn)行處理,也不需要大量的帶寬來(lái)發(fā)送響應。
結束語(yǔ)
對于很多 ajax 和 web 程序員來(lái)說(shuō),本文中介紹的內容似乎是太高級了。生成 head 請求的價(jià)值是什么呢?到底在什么情況下需要在 javascript 中顯式地處理重定向狀態(tài)代碼呢?這些都是很好的問(wèn)題;對于簡(jiǎn)單的應用程序來(lái)說(shuō),答案是這些高級技術(shù)的價(jià)值并不是非常大。
然而,web 已經(jīng)不再是只需實(shí)現簡(jiǎn)單應用程序的地方了;用戶(hù)已經(jīng)變得更加高級,客戶(hù)期望能夠獲得更好的穩定性、更高級的錯誤報告,如果應用程序有 1% 的時(shí)間停機,那么經(jīng)理就可能會(huì )因此而被解雇。
因此您的工作就不能僅僅局限于簡(jiǎn)單的應用程序了,而是需要更深入理解 xmlhttprequest。
如果您可以考慮各種就緒狀態(tài) —— 并且理解了這些就緒狀態(tài)在不同瀏覽器之間的區別 —— 就可以快速調試應用程序了。您甚至可以基于就緒狀態(tài)而開(kāi)發(fā)一些創(chuàng )造性的功能,并向用戶(hù)和客戶(hù)回報請求的狀態(tài)。
如果您要對狀態(tài)代碼進(jìn)行控制,就可以設置應用程序來(lái)處理腳本錯誤、非預期的響應以及邊緣情況。結果是應用程序在所有的時(shí)間都可以正常工作,而不僅僅是只能一切都正常的情況下才能運行。
增加這種生成 head 請求的能力,檢查某個(gè) url 是否存在,以及確認某個(gè)文件是否被修改過(guò),這樣就可以確保用戶(hù)可以獲得有效的頁(yè)面,用戶(hù)所看到的信息都是最新的,(最重要的是)讓他們驚訝這個(gè)應用程序是如何健壯和通用。
本文的目的并非是要讓您的應用程序顯得十分華麗,而是幫助您去掉黃色聚光燈后重點(diǎn)昭顯文字的美麗,或者外觀(guān)更像桌面一樣。盡管這些都是 ajax 的功能(在后續幾篇文章中就會(huì )介紹),不過(guò)它們卻像是蛋糕表面的一層奶油。如果您可以使用 ajax 來(lái)構建一個(gè)堅實(shí)的基礎,讓?xiě)贸绦蚩梢院芎玫靥幚礤e誤和問(wèn)題,用戶(hù)就會(huì )返回您的站點(diǎn)和應用程序。