ajax|object|request|錯誤
Ajax Hacks-hack8 處理Request Object 的錯誤
讓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”>
Your total Stock Holdings
javascript:void%200>“getStockPrice(this.stSymbol.value,this.numShares.value);return false”>
Enter stock symbol:
Enter share amount:
Get Total Value
When users load this file into their browsers, they see the screen shown in Figure 1-11.
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常見的異常以及捕獲他們的辦法。
<