讓AJax能檢測服務器的錯誤,並能像用戶提供有用的信息。
AJax技術的魅力在於允許Javascript能在用戶不干預的情況下與服務器連接。然而JavaScript開發者經常無法控制服務器組件(可能是一個web服務或其他軟件)。盡管你的應用程序包括了你自己的服務器組件,也無法保證服務器永遠運行正常或者用戶遇到錯誤。因此,當程序出錯時候,必須保證應用產業程序能恢復。
本hack跟蹤錯誤並顯示出錯誤信息,當AJax程序失去服務器連接的時候。
問題, 問題...
Hack捕獲下列異常事件,並為應用程序推薦解決的辦法:
正在連接的web應用程序或服務器組件暫時不可用。
應用程序連接的服務器掛掉了,或者URL改變了。
要連接的服務器組件錯誤,在連接的過程中發作了。
當requst對象調用open方法時,代碼使用了不同的主機地址而不是用戶下載的web頁面地址。當調用open方法時,request對象拋出一個異常。
你可以在其他地方使用本hack的異常處理方法。hack還使用了hack6種的股票計算程序代碼。看一下Html代碼:
“http://www.w3.org/TR/1999/REC-Html401–19991224/strict.dtd”>
Figure 1-11. Request a stock’s price
我們感興趣的代碼是能捕獲異常的部分,後台服務器關閉、錯誤、或者錯誤的URL。handleResponse函數是事件處理函數用來管理服務器響應,request.onreadystatechange=handleResponse。接下來的代碼使用try/catch/finally 來捕獲並處理無效數字這一問題。
function handleResponse( ){
var statusMsg=“”;
try{
if(request.readyState == 4){
if(request.status == 200){
/* Check if the return value is actually a number.
If so, multiple by the number
of shares and display the result */
var stockPrice = request.responseText;
try{
if(isNaN(stockPrice)) { throw new Error(
“The returned price is an invalid number.”;}
if(isNaN(numberOfShares)) { throw new Error(
“The share amount is an invalid number.”;}
var info = “Total stock value: $”+
calcTotal(stockPrice);
displayMsg(document.
getElementById(“msgDisplay“,info,“black”;
document.getElementById(“stPrice“.style.fontSize=”0.
9em”;
document.getElementById(“stPrice“.innerHtml =“price: ”+
stockPrice;
} catch (err) {
displayMsg(document.getElementById(“msgDisplay”,
“An error occurred: ”+
err.message,“red”;
}
} else {
//request.status is 503 if the application isn‘t available;
//500 if the application has a bug
alert(
“A problem occurred with communicating between the ”
“XMLHttpRequest object and the server program. ”+
“Please try again very soon”;
}
}//end outer if
} catch (err) {
alert(“It does not appear that the server ”+
“is available for this application. Please ”+
“try again very soon. \\nError: ”+err.message);
}
}
下面看一下用來處理不同異常的代碼。
try塊將拋出內部的任何異常,而相應的catch將捕獲這個異常,並解決異常。try catch是相對的。
當主機掛掉了會發生什麼呢?盡管你請求的URL是正確的。這種情況下,試圖訪問request.status 屬性的代碼會拋出一個異常,應為request對象沒有從服務器接收到響應,以及相應的狀態屬性。
因此,代碼會彈出一個警告對話框來提示用戶。
Figure 1–12 depicts what the alert window looks like after this type of error.
Figure 1-12. Uh-oh, server down
代碼顯示了用戶的信息,以及更多異常錯誤的相關信息。你可以不管學些信息,不過這些對程序的修改和調試很有幫助。
代碼裡的錯誤變量是Javascript錯誤對象。對象的信息屬性就是一個錯誤信息,是由JavaScript引擎產生的string。
如果沒有使用 TRy/catch/finally 機制,用戶只能看到很不容易懂得由JavaScript引擎產生的錯誤信息。在關閉這個討厭的錯誤提示框以後,用戶就無法了解應用程序的更多狀態信息了。
有時,服務器或主機運行正常,但是要連接的服務器組件有問題。這樣的情況下,request.status 屬性的值是503(服務不可用)。因為狀態屬性的值不是200,代碼的這一部分將捕獲這個異常:
} else {
//request.status is 503 if the application isn‘t available;
// 500 如果服務有錯誤
alert(
“A problem occurred with communicating between the ”
“XMLHttpRequest object and the server program. ”+
“Please try again very soon”;
}
換句話說,用戶可以在彈出窗口中看到應用程序狀態信息。也可以顯示服務器組件的錯誤。這樣的情況下,響應狀態碼是500(內部服務錯誤)。此外404狀態響應碼表示服務器的靜態或動態組件無法找到請求的URL,就是常見的令人討厭的400錯誤(頁面不存在或被刪除)。
try/catch/finally語句只適用於1.4或更高的版本中。finally語句是可選的。
令人沮喪的錯誤的URL
如果用戶請求的URL是錯誤的或已經改變了,會發生什麼呢? 調用request.open方法會拋出異常,因此必須放在try/catch/finally語句裡邊處理。
在犯法initReq( )裡邊,有相應的代碼:
function httpRequest(reqType,url,asynch){
//Mozilla-based browsers
if(window.XMLHttpRequest){
request = new XMLHttpRequest( );
} else if (window.ActiveXObject){
request=new ActiveXObject(“Msxml2.XMLHTTP”;
if (! request){
request=new ActiveXObject(“Microsoft.XMLHTTP”;
}
}
//the request could still be null if neither ActiveXObject
//initialization succeeded
if(request){
initReq(reqType,url,asynch);
} else {
alert(“Your browser does not permit the use of all ”+
“of this application‘s features!”;
}
}
/* Initialize a request object that is already constructed */
function initReq(reqType,url,bool){
try{
/* Specify the function that will handle the HTTP response */
request.onreadystatechange=handleResponse;
request.open(reqType,url,bool);
request.send(null);
} catch (err) {
alert(
“The application cannot contact the server at the moment.”+
“ Please try again in a few seconds.”;
}
}
另一種情況是請求的URL不是所想的。例如,用戶想從http://www.myorg.com/app下載頁面,但是打開的URL卻是http://www.myorg.com,這樣的錯誤也可以使用try/catch/finally 語句捕獲。
本hack講述了AJax常見的異常以及捕獲他們的辦法。