WINDOWS2000搭載ASP3.0和IIS5.0

网络整理 - 09-14
相信大部分的人目前所用的ASP版本都是搭載在IIS3.0或IIS4.0中的ASP2.0,伺服器平台也多是NT4.0,隨著WINDOWS 2000 即將在二月十七號問世,由於之前許多雜誌媒體都曾經報導過有關WINDOWS 2000在伺服器性能的擴充以及各版本(伺服器版本,個人用戶版本....)的簡介,所以大家都迫不及待的想知道WINDOWS 2000到底多了哪些強大的功能,身為NT 伺服器使用者的我們當然也不可不知到底微軟在這方面改善了多少?不過由於本版面主要是在討論ASP的應用,所以筆者將針對搭載在WINDOWS 2000中的ASP3.0和IIS5.0與之前IIS3.0或IIS4.0中的ASP2.0有增加了哪些元件或者是擴充的屬性與方法來說明,總體來說,ASP20.與ASP3.0並沒有許多的不同,比較引人注意的是新增了兩個伺服器物件方法(METHOD)---SERVER.EXECUTE和SERVER.TRANSFER以及一個新增加的物件--ASPERROR物件。

SERVER.TRANSFER方法

以往ASP2.0中控制兩個網頁之間的傳遞大部分都是靠Response.Redirect來完成,但是一般人可能不曉得Response.Redirect在應用上來說是相當笨拙的,在ASP處理Response.Redirect時是先將一個訊息傳遞至客戶端的瀏覽器,告知客戶端的瀏覽器準備載入一個新的網址,客戶端瀏覽器接收到這筆訊息之後再回傳一個確認新網址訊息回伺服器端,然後伺服器端再將客戶端瀏覽器導向到新的網址,在網路蓬勃發展的今天,這樣的做法勢必會對網路的堵塞情形帶來更大的衝擊,而這也是使用者與網站管理者所不樂於見到的,為了取代Response.Redirect這個笨方法,ASP3.0加入了一個新的伺服器方法--SERVER.TRANSFER,把Response.Redirect中客戶端與伺服器端的溝通全部轉移到伺服器上,所有的處理程序全部交由伺服器來執行,當然啦!!在語法與應用的觀念上與Response.Redirect並無太大的分別,在網頁與網頁中傳遞資訊時,所有的時域變數和應用程式變數都將保持不變,看看下面的說明:

語法
SERVER.TRANSFER(PATH)

PATH所定義的是將控制權轉移到的目的網頁之網址,跟Response.Redirect後面所接的

參數有異曲同工之妙,舉例來說,

ASP1.asp如下:

<HTML>
<BODY>
<%
Response.Write Session.SessionID

Response.Write ("<BR>")

Response.Write("我要到下一個網頁去囉!! <BR>")

Server.Transfer("ASP2.asp")
%>

ASP2.asp如下
<HTML>
<BODY>
<%

Response.Write Session.SessionID
%>

ASP1.asp執行結果如下

一個SessionID
我要到下一個網頁去囉!!
同樣的SessionID

很明顯的可以看出Response.Redirect與SERVER.TRANSFER的不同了吧!!

SERVER.EXECUTE方法

SERVER.EXECUTE跟SERVER.TRANSFER相同的是都是在進行script執行程序的轉移,唯一不同的是SERVER.TRANSFER最後將控制權交給被呼叫的script檔案,而SERVER.EXECUTE最後將控制權轉移給被呼叫者本身,也就是說執行SERVER.EXECUTE的script檔案將被呼叫的script檔案視做自己本身的一部份,在觀念上來說,與Include的做法是一樣的,與許多高階語言呼叫副程式的做法也相同,基本上伺服器端允許SERVER.EXECUTE修改Http標題,但是如果被執行的檔案企圖在傳送訊息至客戶端瀏覽器之後修改Http標題就會發生已將 HTTP 標題寫入用戶端瀏覽器。對任何 HTTP 的標題所做的修改必須要在寫入頁內容之前的錯誤。看看下面的範例:
ASP1
<HTML>
<BODY>
<% Response.Write("你在看我嗎? <BR>")
Server.Execute("asp2.asp")
%>
</BODY>
</HTML>
ASP2
<HTML>
<BODY>
<% Response.Write("你可以再近一點。")%>
</BODY>
</HTML>
ASP1.asp執行結果將會是

你在看我嗎?
你可以再近一點。

  看完了這兩個新增加的伺服器物件屬性之後,接下來讓我們看看新增加的ASP內建元件--ASPERROR元件,這是ASP3.0所提供的一個全新的元件,他讓網站管理者能完全掌控因ASP所產生的錯誤,這是前幾個版本所無法做到的,在前幾個版本中要捕捉因ASP所發生的錯誤是不可能的,頂多只能用VBscript的On Error Resume Next來捕捉到因script所發生的錯誤,任何COM或ASP所發生的錯誤都無法捕捉,隨著ASP3.0的到來,這些問題都將迎刃而解。

  為了要使用ASPERROR物件你必須會使用IIS的Http錯誤控制,不曉得大家進我們網站之後有沒有發現,當你在網址後亂打一些字然後再按Enter你會發現當網址不存在時會出現如下的畫面:

  這個就叫做自定錯誤頁面,大家知道這是如何做到的嗎?打開NT的IIS伺服器管理員之後,在站台名稱之上點選滑鼠右鍵,選擇內容(最下面的選項)你可以看到看看下面的畫面(由於筆者的工作平台是Window 98)所以只好藉由測試平台(英文版的NT來為大家做一個說明)。

  你可以看到許多的控制選項,選擇右上角的Custom Errors(自定錯誤),然後選取404這個錯誤,你會看到在內容部分會有一個路徑的描述C:\WINNT|help\common\404b.htm
這個檔案放置的內容就是在描述當所查詢的網址不存在時會發生的錯誤訊息,404b.htm的原始檔如下:

404b.htm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>

<head>
<style>
a:link {font:9pt/12pt 新細明體; color:red}
a:visited {font:9pt/12pt 新細明體; color:#4e4e4e}
</style>
<meta HTTP-EQUIV="Content-Type" Content="text-html; charset=big5">
<title>HTTP 404 找不到</title>
</head>
<script>

function Homepage(){
// in real bits, urls get returned to our script like this:
// res://shdocvw.dll/http_404.htm#

//For testing use DocURL = "res://shdocvw.dll/http_404.htm#https://www.microsoft.com/bar.htm"
DocURL = document.location.href;

//this is where the http or https will be, as found by searching for :// but skipping the res://
protocolIndex=DocURL.indexOf("://",4);

//this finds the ending slash for the domain server
serverIndex=DocURL.indexOf("http://www.cuoxin.com/",protocolIndex + 3);

//for the href, we need a valid URL to the domain. We search for the # symbol to find the beginning
//of the true URL, and add 1 to skip it - this is the BeginURL value. We use serverIndex as the end marker.
//urlresult=DocURL.substring(protocolIndex - 4,serverIndex);
BeginURL=DocURL.indexOf("#",1) + 1;
if (protocolIndex - BeginURL > 7)
urlresult=""

urlresult=DocURL.substring(BeginURL,serverIndex);

//for display, we need to skip after , and go to the next slash
displayresult=DocURL.substring(protocolIndex + 3 ,serverIndex);

// Security precaution: must filter out "urlResult" and "displayresult"
forbiddenChars = new RegExp("[<>\'\"]", "g"); // Global search/replace
urlresult = urlresult.replace(forbiddenChars, "");
displayresult = displayresult.replace(forbiddenChars, "");

document.write('<A target=_top HREF="' + urlresult + '">' + displayresult + "</a>");

}

</script>

<body bgcolor="white">
<object id=saOC CLASSID='clsid:B45FF030-4447-11D2-85DE-00C04FA35C89' HEIGHT=0 width=0></object>

<table cellpadding="3" cellspacing="5">
<tr>
<td valign="top"><img SRC="http://www.xbasp.net/pagerror.gif"
width="25"></td>
<td valign="middle"><h1
style="COLOR: black; FONT: 12pt/15pt 新細明體"><span><b>找不到網頁</b></span></h1>
</td>
</tr>
<tr>
<td colspan="2"><font
style="COLOR: black; FONT: 9pt/12pt 新細明體">查詢的網頁可能已經移除、變更名稱或者暫時無法使用。</font></td>
</tr>
<tr>
<td colspan="2"><font
style="COLOR: black; FONT: 9pt/12pt 新細明體"><hr color="#C0C0C0" noshade>
<p>請嘗試下列:</p><ul>
<li>如果在網址列輸入網址,請確定未拼錯任何資料。<br>
</li>
<li>開啟 <script> Homepage(); </script> 首頁,然後查詢您想索取之資訊的連結。
</li>
<li>按<a href="javascript:history.back(1)"><img valign=bottom border=0 src="http://www.xbasp.net/back.gif"> [上一頁] </a>按鈕,移到其它連結。</li>
<li>按一下<a onclick="saOC.NavigateToDefaultSearch();event.returnValue=false" href=""><img border=0 src="http://www.xbasp.net/search.gif" alt="http://www.xbasp.net/search.gif (114 位元組)"> [搜尋] </a>來尋找 Internet 資訊。 </li>
</ul>
<p><br>
</p>
<h2>HTTP 404 - 找不到檔案<br>
Internet Explorer <BR>
</h2>
</font></td>

</tr>
</table>
</body>
</html>

一般未使用自定錯誤之前,你所應該看到的畫面應該如下圖所示

  至於藍色那一段網址超連結的部分是透過404b.htm中Homepage()函數來解析所獲得的,要使用自己所定義的錯誤頁面有兩種方式可以完成,第一種是直接將自己所做的錯誤頁面存到C:\WINNT\help\common\404b.htm記得檔名要取一樣,第二個是將錯誤頁面儲存到你想存放的目錄之下,然後直接修改站台內容中自定錯誤選項中的錯誤頁面存放路徑,如下圖所示:

其中的就是以URL為基準的存放路徑。

在IIS4.0中我們只能夠捕捉到404的錯誤訊息,但是IIS5.0卻能利用ASP程式捕捉伺服器應用程式500和100錯誤(在編譯或執行ASP程式時所發生的錯誤)的訊息,並在捕捉到訊息之後執行你想執行的ASP程式,譬如將使用者導向到某個網頁,這樣的方式讓使用者不必再忍受一但瀏覽網路時遭遇到錯誤而無所適從的困境,因為使用者多半不曉得發生什麼事,如果透過網站管理員告知使用者將會讓使用者覺得更貼心。
ASPERROR物件該如何使用呢?基本上他必須搭配SERVER物件的新方法GetLastError來使用,因為ASPERROR物件是透過Server.GetLastError方法來傳回錯誤訊息的。譬如說你將IIS5.0設定成當捕捉到伺服器應用程式500或100錯誤訊息之後將使用者導向到Error.asp,並利用Error.asp來描述所發生的錯誤,讓我們看看Error.asp在做些什麼事。
Error.asp

<%
Dim objLastASPError

'建立伺服器物件(取得ASP所產生的最後一項錯誤)

Set objLastASPError = Server.GetLastError

'描述錯誤情況
%>

  伺服器遭遇如下的錯誤:<BR>
描述: <%=objLastASPError.Description%><BR>
錯誤類別: <%=objLastASPError.Category%><BR>
發生錯誤的檔案: <%=objLastASPError.File%><BR>
元件錯誤碼: <%=objLastASPError.Number%><BR>

  基本上ASPError物件還有許多屬性,而這些屬性通通都是要靠建立伺服器物件,並以伺服器物件中的GetLastError方法來傳回錯誤訊息,讓我們看看ASPError物件還有哪些屬性:
ASPCODE:傳回IIS所產生的錯誤碼

NUMBER:傳回COM物件所產生的錯誤碼

SOURCE:傳回產生錯誤的那段原始程式

CATEGORY:如果是ASP內部產生錯誤,那會傳回是COM還是手稿語言的錯誤

file:傳回產生錯誤的ASP檔案名稱

LINE:指出是哪一行程式發生錯誤,傳回行數

DEscriptION:傳回簡短錯誤訊息

ASPDEscriptION:傳回詳細錯誤訊息

  基本上這就是IIS5.0中的ASP3.0和IIS4.0中的ASP2.0所不同之處,當然啦,還有許多小地方也改了,只是比較不受人注意所以沒有寫出來,像IIS4.0中Response.Buffer的預設值是False,若使用者需要再將其開啟,但是IIS5.0為了提昇效能直接就將預設值設定為True,奇怪,既然能提昇效能為什麼IIS4.0要將他設定為False,打個電話去問比爾吧!!我也不知道。