直播中
ASPCode
整型。由ASP/IIS產(chǎn)生的錯(cuò)誤號(hào),例如0x800A009
ASPDescription
字符串型。如果這個(gè)錯(cuò)誤是與ASP相關(guān)的錯(cuò)誤,這個(gè)屬性是錯(cuò)誤的詳細(xì)說(shuō)明
Category
字符串型。錯(cuò)誤源,即ASP內(nèi)部腳本語(yǔ)言、或一個(gè)對(duì)象
Column
整型。產(chǎn)生錯(cuò)誤的文件中的字符位置
Description
字符串型。錯(cuò)誤的簡(jiǎn)短說(shuō)明
File
字符串型。錯(cuò)誤出現(xiàn)時(shí)正在處理的文件的名稱
Line
整型。產(chǎn)生錯(cuò)誤的文件中的行號(hào)
Number
整型。一個(gè)標(biāo)準(zhǔn)的COM錯(cuò)誤代碼
Source
字符串型。引發(fā)錯(cuò)誤的行的實(shí)際代碼
3. 配置“單個(gè)網(wǎng)頁(yè)”錯(cuò)誤處理
在IIS中“不可思議”地出現(xiàn)一個(gè)錯(cuò)誤(例如404 Not Found)時(shí),頁(yè)面看起來(lái)像是從服務(wù)器返回給客戶端的一個(gè)錯(cuò)誤信息頁(yè)面,但實(shí)際上并不是這樣。它們是普通的HTML網(wǎng)頁(yè),在對(duì)一個(gè)錯(cuò)誤進(jìn)行響應(yīng)時(shí)被下載并且發(fā)送給客戶端。這些網(wǎng)頁(yè)通常稱為定制的錯(cuò)誤網(wǎng)頁(yè)(custom error page)。
然而,錯(cuò)誤網(wǎng)頁(yè)作為IIS的缺省安裝部分,可根據(jù)要求定制。事實(shí)上,也可以在IIS的早期版本中建立定制的錯(cuò)誤網(wǎng)頁(yè)。
在IIS 4.0中,可以為每種不同類型的HTTP協(xié)議或服務(wù)器錯(cuò)誤指定一個(gè)定制的錯(cuò)誤網(wǎng)頁(yè),為服務(wù)器上任意的Web網(wǎng)站中的每個(gè)目錄建立一個(gè)定制的錯(cuò)誤信息網(wǎng)頁(yè)。
(1) IIS缺省的錯(cuò)誤網(wǎng)頁(yè)
由IIS提供的缺省錯(cuò)誤頁(yè)面放在Web服務(wù)器的WinNT\Help目錄中。在Windows 2000中的IIS 5.0的環(huán)境下,該頁(yè)面放在WinNT\Help\iishelp\common目錄下,如圖4-17所示:
圖4-17 缺省的錯(cuò)誤頁(yè)面位置
可在瀏覽器中打開這些文件查看結(jié)果,或者在文本編輯器中查看HTML源程序和腳本代碼。當(dāng)一個(gè)404錯(cuò)誤出現(xiàn)時(shí),使用的頁(yè)面是404b.htm,這個(gè)文件包含一個(gè)客戶端腳本代碼部分,它獲得當(dāng)前文檔的URL(從document對(duì)象的url屬性中檢索)并在該頁(yè)面中顯示:
<tr>
<td width="400" colspan="2"> <font style="COLOR:000000; FONT: 9pt/11pt 宋體">您正在搜索的網(wǎng)頁(yè)可能已經(jīng)刪除、更名或暫時(shí)不可用。</font></td>
</tr>
<tr>
<td width="400" colspan="2"> <font style="COLOR:000000; FONT: 9pt/11pt 宋體">
<hr color="#C0C0C0" noshade>
<p>請(qǐng)嘗試下列操作:</p>
<ul>
<li>如果您在“地址”欄中鍵入了網(wǎng)頁(yè)地址,請(qǐng)檢查其拼寫是否正確。<br>
</li>
<li>打開 <script>
<!--
if (!((window.navigator.userAgent.indexOf("MSIE") > 0) && (window.navigator.appVersion.charAt(0) == "2")))
{
Homepage();
}
//-->
</script> 主頁(yè),尋找指向所需信息的鏈接。</li>
…
<script>
function Homepage(){
<!--
DocURL = document.URL;
protocolIndex=DocURL.indexOf("://",4);
serverIndex=DocURL.indexOf("/",protocolIndex + 3);
BeginURL=DocURL.indexOf("#",1) + 1;
urlresult=DocURL.substring(BeginURL,serverIndex);
displayresult=DocURL.substring(protocolIndex + 3 ,serverIndex);
document.write('<A HREF="' + urlresult + '">' + displayresult + "</a>");
}
//-->
</script>
這會(huì)產(chǎn)生你經(jīng)??吹降捻?yè)面,如圖4-18所示:
圖4-18 產(chǎn)生404錯(cuò)誤時(shí)的頁(yè)面
(2) IIS中錯(cuò)誤網(wǎng)頁(yè)的映射
當(dāng)IIS檢測(cè)到一個(gè)錯(cuò)誤時(shí),會(huì)把相應(yīng)的錯(cuò)誤頁(yè)面?zhèn)魉徒o客戶端。如何判別應(yīng)該向客戶端發(fā)送那一個(gè)頁(yè)面?很明顯,網(wǎng)頁(yè)的名字應(yīng)具有解決這個(gè)問題的一些信息,但事實(shí)上文件名是不重要的。錯(cuò)誤和錯(cuò)誤網(wǎng)頁(yè)文件之間的映射關(guān)系是在每個(gè)目錄的properties對(duì)話框的Custom Errors選項(xiàng)卡中決定的。
在Internet Services Manager中,在想編輯映射關(guān)系的目錄上單擊右鍵,并選擇Properties。如果對(duì)示例文件進(jìn)行設(shè)置,在Chapter04目錄中選擇server子目錄,如圖4-19所示:
圖4-19 設(shè)置屬性時(shí)的頁(yè)面屏幕
Properties對(duì)話框的Custom Errors選項(xiàng)卡在IIS安裝時(shí)(除非已經(jīng)進(jìn)行過(guò)修改)設(shè)置了缺省映射關(guān)系的列表,如圖4-20所示:
圖4-20 映射關(guān)系的列表
靠近該列表的底部是HTTP錯(cuò)誤500:100的一個(gè)條目。類型500錯(cuò)誤是由ASP產(chǎn)生的,可以從中看出一些錯(cuò)誤已經(jīng)與錯(cuò)誤網(wǎng)頁(yè)建立了映射關(guān)系。這些錯(cuò)誤都是一般性的錯(cuò)誤,比如“Invalid Application”、“Server Shutting Down”等等。然而,如果ASP載入包含語(yǔ)法錯(cuò)誤的頁(yè)面,或者出現(xiàn)一個(gè)運(yùn)行期錯(cuò)誤,則出現(xiàn)500:100錯(cuò)誤頁(yè)面。在列表中顯示的缺省映射關(guān)系表明,在這個(gè)目錄中的一個(gè)文件出現(xiàn)上述錯(cuò)誤時(shí),將執(zhí)行500-100.asp頁(yè)面。
當(dāng)一個(gè)ASP錯(cuò)誤出現(xiàn)時(shí),我們所看到的信息不再是一個(gè)普通的Web網(wǎng)頁(yè),而是一個(gè)ASP Web網(wǎng)頁(yè)(也就是說(shuō)它具有文件擴(kuò)展名.asp)。也可以根據(jù)需要編輯該映射關(guān)系來(lái)指向另一個(gè)頁(yè)面。
(3) 指定一個(gè)定制的錯(cuò)誤網(wǎng)頁(yè)
單擊Custom Errors選項(xiàng)中的Edit Properties按鈕,打開Error Mapping Properties對(duì)話框。在Message Type下拉列表中選擇URL,鍵入自己的定制錯(cuò)誤網(wǎng)頁(yè)的完整虛擬路徑,如圖4-21所示:
圖4-21 指定錯(cuò)誤頁(yè)面的虛擬路徑的屏幕
在圖4-21中給出的值指向我們創(chuàng)建的與示例網(wǎng)頁(yè)一起使用的一個(gè)定制錯(cuò)誤網(wǎng)頁(yè)。根據(jù)你安裝示例文件的具體位置,可能要使用不同的路徑。
現(xiàn)在無(wú)論何時(shí)出現(xiàn)一個(gè)500:100類型的錯(cuò)誤,將打開我們的定制錯(cuò)誤頁(yè)面。Message Type的其他兩個(gè)選項(xiàng)是:
· Default(缺?。嚎梢院?jiǎn)單地輸入一個(gè)短的文本信息,而不是指定一個(gè)發(fā)送給客戶端的頁(yè)面。
· File(文件):指定一個(gè)HTTP錯(cuò)誤網(wǎng)頁(yè)的物理路徑。
在選擇File選項(xiàng)時(shí),指定的網(wǎng)頁(yè)由IIS載入,載入的方式與在Windows Explorer中雙擊要載入的文件時(shí)的方式相同。這意味著ASP網(wǎng)頁(yè)不能使用這個(gè)選項(xiàng),因?yàn)樵谶@種情況下不會(huì)執(zhí)行其中的任何腳本。
4. 使用GetLastError方法和ASPError對(duì)象
配置好IIS后,在編輯了錯(cuò)誤映射屬性的目錄內(nèi)的任一頁(yè)面上出現(xiàn)一個(gè)與ASP相關(guān)的錯(cuò)誤時(shí),都將載入定制錯(cuò)誤頁(yè)面。實(shí)際上,現(xiàn)在已經(jīng)設(shè)置了一個(gè)正常的腳本錯(cuò)誤陷阱,因?yàn)樵谶@個(gè)目錄內(nèi)的任何一個(gè)網(wǎng)頁(yè)上的ASP運(yùn)行期錯(cuò)誤都將觸發(fā)定制錯(cuò)誤頁(yè)面。
事實(shí)上在內(nèi)部IIS通過(guò)Server.Transfer方法進(jìn)行這種操作,這意味著能夠訪問正在運(yùn)行的原網(wǎng)頁(yè)的全部環(huán)境??梢栽谀_本環(huán)境中獲取信息,這樣可以根據(jù)所出現(xiàn)的錯(cuò)誤決定要做些什么。在此基礎(chǔ)上,可以在定制的錯(cuò)誤網(wǎng)頁(yè)中檢索ASPError對(duì)象,找到引起載入頁(yè)面出錯(cuò)的錯(cuò)誤的所有信息。
在IIS 4.0中,編輯錯(cuò)誤映射屬性要做一些類似的工作。但是只有一般的500錯(cuò)誤(“Internal Server Error”)在映射中是可用的。另外,當(dāng)定制錯(cuò)誤網(wǎng)頁(yè)載入時(shí),不會(huì)傳送網(wǎng)頁(yè)的環(huán)境,除了提供一個(gè)非特定的錯(cuò)誤信息外,做其他任何工作都是比較困難的。
在以前例子中已經(jīng)使用過(guò)ASP Server Object示例頁(yè)面,在其中可以看到ASPError對(duì)象的詳細(xì)情況。單擊Server.GetLastError()對(duì)應(yīng)的按鈕,如圖4-22所示:
圖4-22 查看ASPError對(duì)象的詳細(xì)屏幕
這個(gè)操作會(huì)重新載入該網(wǎng)頁(yè),其中的ASP腳本查看點(diǎn)擊的是哪個(gè)按鈕。如果是Server.GetLastError()對(duì)應(yīng)的名為cmdGetError的按鈕,將執(zhí)行一些示例代碼,這些代碼將會(huì)產(chǎn)生一個(gè)運(yùn)行期腳本錯(cuò)誤。
…
If Len(Request.Form(“cmdGetError”)) Then
Dim arrThis(3)
ArrThis(4) = “Causes an error”
End If
…
因?yàn)橐褜?duì)這個(gè)目錄設(shè)置了錯(cuò)誤網(wǎng)頁(yè)映射,即配置為裝入定制錯(cuò)誤頁(yè)面,所以當(dāng)錯(cuò)誤出現(xiàn)時(shí),就打開這個(gè)頁(yè)面(通過(guò)Server.Transfer方法在后臺(tái)不可見地工作),見圖4-23所示:
圖4-23 定制的錯(cuò)誤網(wǎng)頁(yè)
(1) 示例錯(cuò)誤網(wǎng)頁(yè)代碼的功能
定制錯(cuò)誤網(wǎng)頁(yè)顯示ASPError對(duì)象屬性的所有值,并通過(guò)使用Response.Status方法,把一個(gè)HTTP報(bào)頭狀態(tài)消息返回給客戶端,指明出現(xiàn)了一個(gè)錯(cuò)誤。接著使用GetLastError方法獲取對(duì)ASPError對(duì)象的一個(gè)引用,因此可以訪問錯(cuò)誤的詳細(xì)數(shù)據(jù):
…
<%
Response.Status = "500 Internal Server Error"
Set objASPError = Server.GetLastError()
%>
Currently executing the page: <B>show_error.asp</B><P>
<B>Error Details:</B><BR>
ASPError.ASPCode = <% = objASPError.ASPCode %><BR>
ASPError.Number = <% = objASPError.Number %> (0x<% = Hex(objASPError.Number) %>)<BR>
ASPError.Source = <% = Server.HTMLEncode(objASPError.Source) %><BR>
ASPError.Category = <% = objASPError.Category %><BR>
ASPError.File = <% = objASPError.File %><BR>
ASPError.Line = <% = objASPError.Line %><BR>
ASPError.Column = <% = objASPError.Column %><BR>
ASPError.Description = <% = objASPError.Description %><BR>
ASPError.ASPDescription = <% = objASPError.ASPDescription %>
<FORM ACTION="<% = Request.ServerVariables("HTTP_REFERER") %>" METHOD="POST">
<INPUT TYPE="SUBMIT" NAME="cmdOK" VALUE=" ">
Return to the previous page<P>
</FORM>
值得注意的一點(diǎn)是,如果一個(gè)腳本或ASP錯(cuò)誤出現(xiàn)在定制錯(cuò)誤網(wǎng)頁(yè)中,IIS將僅僅返回一個(gè)與錯(cuò)誤代碼500:100對(duì)應(yīng)的一般性消息。這可能是腳本引擎自己的錯(cuò)誤消息,或者只是相當(dāng)簡(jiǎn)單的消息:“Internal Server Error”。不會(huì)再次重新載入定制的錯(cuò)誤網(wǎng)頁(yè)。
包含錯(cuò)誤的網(wǎng)頁(yè)的全部環(huán)境將傳送給定制錯(cuò)誤網(wǎng)頁(yè)。也就是說(shuō),可以使用存儲(chǔ)在任何ASP內(nèi)部對(duì)象集合或?qū)傩灾械闹?。例如,如果檢索來(lái)自Request.ServerVariables集合的HTTP_REFERER值,它將反映調(diào)用原網(wǎng)頁(yè)的網(wǎng)頁(yè)(即在錯(cuò)誤出現(xiàn)之前的網(wǎng)頁(yè))的URL。在服務(wù)器把執(zhí)行轉(zhuǎn)到錯(cuò)誤網(wǎng)頁(yè)時(shí),這個(gè)值不會(huì)發(fā)生變化,并且它將不包含當(dāng)錯(cuò)誤發(fā)生時(shí)正在執(zhí)行的網(wǎng)頁(yè)的URL。
同樣,SCRIPT_NAME值將是包含該錯(cuò)誤的網(wǎng)頁(yè)的名字,而不是錯(cuò)誤網(wǎng)頁(yè)的URL。在一個(gè)錯(cuò)誤網(wǎng)頁(yè)已經(jīng)裝入時(shí),通過(guò)檢查瀏覽器地址欄中的URL,可以對(duì)此進(jìn)行確認(rèn)。但是在原網(wǎng)頁(yè)的腳本變量中存儲(chǔ)的值,在定制的錯(cuò)誤網(wǎng)頁(yè)中都是不可用的。
如果原ASP網(wǎng)頁(yè)正在一個(gè)事務(wù)內(nèi)運(yùn)行,即在網(wǎng)頁(yè)的最前面包含有一個(gè)<% @TRANSACTION=”…” %>指令,也應(yīng)該確定是否需要在網(wǎng)頁(yè)中采取一些方法,以退出該事務(wù)。例如可以調(diào)用內(nèi)置ObjectContext對(duì)象的SetAbort方法:
objectContext.SetAbort ‘Fail the transaction if an ASP error occurs
在本書的后面將介紹與事務(wù)的相關(guān)全部?jī)?nèi)容。
(2) 使用ASPError對(duì)象的屬性
關(guān)于使用ASPError對(duì)象的屬性,有以下幾點(diǎn)值得注意的:
· 即使沒有出現(xiàn)錯(cuò)誤,Number屬性應(yīng)該一直有一個(gè)值。如果ASP網(wǎng)頁(yè)調(diào)用GetLastError方法時(shí)沒有錯(cuò)誤出現(xiàn),該屬性的值是0。通常情況下,對(duì)ASP腳本的運(yùn)行期錯(cuò)誤,Number屬性返回十六進(jìn)制的值“0x800A0000”,加上標(biāo)準(zhǔn)的腳本引擎錯(cuò)誤代碼。例如,前面的例子對(duì)“Subscript out of Range”錯(cuò)誤的返回值為“0x800A0009”,因?yàn)閂BScript對(duì)該類型錯(cuò)誤的錯(cuò)誤代碼是“9”。
· 當(dāng)出現(xiàn)已經(jīng)過(guò)一個(gè)錯(cuò)誤時(shí),Category和Description屬性將一直有一個(gè)值。
· APSCode屬性的值由IIS產(chǎn)生,對(duì)大多數(shù)腳本錯(cuò)誤將為空。更多情況下,涉及外部組件使用出錯(cuò)時(shí)有相應(yīng)的值。
· ASPDescription屬性的值由ASP預(yù)處理程序產(chǎn)生,而不是由當(dāng)前正在使用的腳本引擎產(chǎn)生的,并且對(duì)大多數(shù)腳本錯(cuò)誤而言將是空的。更多情況下,對(duì)諸如對(duì)ASP內(nèi)置對(duì)象調(diào)用無(wú)效的方法的錯(cuò)誤有相應(yīng)的值。
· File、Source、Line和column屬性僅在錯(cuò)誤出現(xiàn)時(shí),并且在錯(cuò)誤的詳細(xì)數(shù)據(jù)是可用的情況下才能進(jìn)行設(shè)置。對(duì)一個(gè)運(yùn)行期錯(cuò)誤,F(xiàn)ile和Line屬性通常是有效的,但是column屬性經(jīng)常返回-1。當(dāng)錯(cuò)誤是一個(gè)阻止頁(yè)面被ASP處理的語(yǔ)法錯(cuò)誤,才返回Source屬性。一般在這些情況下,Line和Column屬性是有效的。如果把Source屬性的值寫到頁(yè)面,明智的辦法是先將該值傳給HTMLEncode,以防在其含有非法的HTML字符。在本章的后面將詳細(xì)地討論HTMLEncode方法。