iis
ASP本身包含了一個DLL檔案,名字為ASP.DLL,預設安裝在Winnt\System32\inetsrv目錄下。這個DLL檔案負責得到一個ASP頁面(由副檔名.ASP標識),然後對它進行分析,尋找伺服器端指令碼內容。這個指令碼傳送給相應的指令碼引擎,指令碼的執行結果與ASP頁中的HTML和模板文本結合在一起。完整的頁面會送到Web伺服器,從那裡送往原先提出請求的用戶端。
關於應用程式的映射
為了更好地理解這個過程,需要研究一下Windows 2000中的應用程式對應的工作方式。對於每一個在IIS下設定好的Web網站,伺服器上都有一個根目錄。安裝IIS時,預設的Web網站通常是C:\InetPub\WWWRoot,除非在安裝過程中改變了路徑。對於這個目錄以及其中的子目錄(這個我們稍後再討論),有一組定義目錄如何配合IIS的屬性。
從Start菜單中的Administrative Tools開啟Internet Services Manger,將運行微軟管理主控台(Microsoft Management Console,MMC ),顯示IIS的情況。
用滑鼠右擊Default Web Site,選擇Properties (屬性),然後出現Home Directory選項卡,如圖1 - 4所示。
可以看到預設的網站被設定成為一個虛擬應用程式。在選項卡的下半部有Applicationname、Execute Permissions和Application Protection選項。IIS使用虛擬應用程式的方式來隔離頁面集和所使用的組件的執行個體,以失敗影響到防止Web伺服器。正如早先所看到的,這是通過在單獨的記憶體空間中執行頁面和進程外組件實現的。我們將在本章後面討論這個問題。
單擊Configuration按鈕開啟Application Configuration對話方塊,見圖1 - 5。在App Mappings選項卡裡,可以看到IIS與各類檔案採用特定的DLL相連結。任何含有擴充檔案名稱.ASP的網頁都送給ASP.DLL進行處理;有未映射的擴充檔案名稱的頁面,如HTML頁面的.HTML和.htm及XML檔案的.xml,只需從磁碟上傳入並直接發送給用戶端。
讀者可能想瞭解這一選項卡上的其他檔案類型。.ida、.idc和.idq副檔名是IDC模板檔案和查詢檔案所使用的,因此,一個IDC查詢頁面( .idc )將直接送到動態連結程式庫httpodbc.DLL進行處理。從檔案名稱也可猜出,它使用ODBC執行SQL語句,返回包含在頁面中的一組資料記錄。同樣, .shtm、.sHTML和.stm副檔名與檔案名稱為ssinc.DLL的動態連結程式庫相對應,這些檔案類型一般用於請求伺服器端包含( server- sideinclude,SSI)處理的檔案。我們將在本書的後續部分給出一些相關的執行個體。
開啟Application Configuration和Properties對話方塊時,讀者可能很想瞭解各個設定的功能。本書的很多地方都要用到這些對話方塊和設定,查看這些設定有助於增加感性認識,但不要改變這些設定,除非知道為什麼這樣做。
處理一個ASP檔案
我們知道一個ASP頁面提供給ASP動態連結程式庫等待解釋和執行,那麼接著ASP會做些什麼呢?
第一步判斷是否有ASP伺服器端的代碼需要執行。假如沒有,它僅是簡單地通知IIS這種情況,並讓IIS向用戶端發送頁面。事實上, Windows 2000的一個新特性允許對所有頁面使用副檔名.ASP,包括對那些非伺服器端的指令碼代碼,而不犧牲任何效能。
在早先版本的IIS和ASP中,所有有.ASP副檔名的頁面,都會被逐行解釋,即使它們含有非ASP伺服器端代碼。這當然要比IIS直接把它們從磁碟發送給用戶端要慢很多。
當ASP從IIS接收到包含有伺服器端指令碼代碼的頁面時,它會逐行進行解釋。那些非伺服器端的指令碼,或不需要ASP進行伺服器處理的,將被返回給IIS,進而發送給用戶端。送來的指令碼都會送給相應的指令碼引擎,指令碼引擎處理後的結果被發送回IIS時,都會插入頁面上相應位置上。
為提高操作的效率, ASP也常把指令碼引擎建立的編譯代碼,放在快取中以備再次調用。這個代碼與發往用戶端的輸出結果是不相同的。客戶看到的是指令碼代碼在經過解釋、語法檢查和編譯後的執行結果。在伺服器上快取的只是編譯後的代碼,在原來的源檔案變化後,這些代碼會被放棄。
1. 辨別伺服器端指令碼段
ASP的解譯器能夠根據兩種分隔方式之一,分辨出代碼是否為伺服器端指令碼。
(1) 用<% %>指令碼分隔字元
< %和% >用以分隔指令碼段的最常用字元是:
這個方法也用於在返回頁面的其餘文本和HTML中需要插入變數值或小段指令碼語句的地方:
這段代碼產生如下結果:
The result of calculating seven plus six minus one is 12
(2) 使用<SCRIPT>元素
當編寫在瀏覽器內執行的指令碼時,使用<SCRIPT>元素。當在此元素中包含了RUNAT屬性並設定其值為“SERVER”時,該元素也可用在伺服器端:
認識到ASP頁面可以包含伺服器端指令碼和用戶端指令碼是很重要的。用戶端的指令碼(包含RUNAT=" CLIENT ",或省略RUNAT屬性)不被ASP解譯器處理,像帶有.htm或. HTML副檔名的普通HTML頁一樣直接送給用戶端:
(3) 包含單獨的指令檔
ASP頁面中能夠包含單獨的檔案,而檔案中包含指令碼代碼,這對編寫可用於其他網頁的通用函數是非常方便的。用這種方法,改變這個檔案中的指令碼代碼,則包含這個檔案的所有指令碼在執行時都自動做相應的改變。為了包含單獨的指令檔,可使用<SCRIPT>元素的S R C屬性,以指定相對的、物理的或虛擬路徑和檔案名稱。
這個單獨的檔案必須僅包含有效指令碼代碼,不能包含原有頁面內容如文本或HTML。假如使用這個技術,其他的代碼不能放在<SCRIPT>元素內,它必須是空的。如果要為頁面增加其他指令碼,需使用另外一個<SCRIPT>元素或者由< % . . . % >分隔的指令碼。
也可以包含來自包含指令碼、文本或HTML的檔案的文本,通過使用伺服器端包含( Server-Side Include,SSI )指令可以實現這一點。在第4章中將研究這個問題。
2. 定義指令碼語言
ASP有兩個指令碼引擎: VBScript和JScript。安裝ASP時這兩個指令碼引擎已預設安裝。也有由其他應用程式使用的指令碼引擎,如微軟的Internet Explorer 網頁瀏覽器和Windows ScriptingHost。在Windows 2000中該瀏覽器的目前版本是5.0,可能還有新的升級版本。還有其他的指令碼引擎,如TCL和PerlScript (一種ActiveX指令碼解譯器而非傳統的基於CGI的Perl )。
因此必須告訴ASP,ASP頁用什麼引擎。通常使用的方法是用特定的環境聲明元素中定義引擎,這必須放在檔案的第一行,並只能定義一次。這個元素一般用在ASP代碼分隔字元後面跟著字元@來表示:
這個定義行還可包含其他的定義內容,在本章後面能看到相關內容。定義一個用VBScript編碼的頁面,如下所示:
<%LANGUAGE="VBScript"%>
對於JScript 引擎,使用:
<%@LANGUAGE="JScript"%>
經過上述定義,在< % . . . % >段內的頁面的所有代碼將被送至定義元素所定義的指令碼引擎。對於這種代碼分隔方式,這是指定指令碼語言的唯一方法。
然而,使用<SCRIPT>定義元素,可以單獨定義每一段的指令碼語言,如果需要的話在同一頁面上可使用不止一種指令碼語言:
不像在用戶端,在注釋元素內不需要隱藏指令碼代碼,因為當它執行時,代碼將從頁面移走,取而代之的僅是輸出結果。在用戶端查看ASP頁(在瀏覽器中選擇View Source)時,只能看到文本、HTML和其他用戶端指令碼代碼。所有的伺服器指令碼都被執行,只有結果被送到用戶端。
預設的指令碼語言
當沒有指定ASP頁的指令碼語言或沒有單獨的<SCRIPT>元素時, ASP將使用預設的指令碼引擎。首次安裝IIS時,預設的指令碼語言是VBScript。但對於整個Web網站或者一個網站內的獨立的虛擬應用程式,根據需要可相應改變設定。
在本章前面提到的Application Configuration對話方塊中,有一個App Options選項卡包含了設定預設語言的文字框,如圖1 - 6所示。
預設語言也可在IIS裡通過編輯Active Directory段的值來改變設定。在Internet ServicesManager MMC外掛程式中所能見到的設定,都存放在Windows 2000中的Active Directory中,只要有相應的許可權就可以進行讀取和編輯。本書將在後面章節詳細介紹Active Directory。
除此以外,可根據個人喜好選擇指令碼語言。假如讀者認為一種語言很好,可一直堅持使用它。因為所有的ASP代碼都在伺服器端執行而不用擔心瀏覽器的相容性問題。假如讀者精通VBScript和JScript或者其他的語言,可根據需要選擇最合適的一種。然而因為VBScript各個版本的功能不斷擴充(例如VBScript 5.0現在支援正規運算式),通常會選擇VBScript。其對類型和文法的要求不是很高,並且有更簡單的多語句結構,因此是一種容易使用的工具。
3. 指令碼效能問題
一般來說,Web伺服器處理器的速度是足夠滿足使用的(除非特別繁忙的網站),因為它們的主要任務是從磁碟中載入頁面並發往用戶端。因此,每個頁面的請求結果都使處理器等待磁碟。這意味著執行ASP指令碼通常對效能的影響非常小。而且如果在一個頁面上某段指令碼代碼多次執行,而這段代碼的已編譯版本已被快取,那麼只須執行它,而不必多次編譯,這樣對效能的影響就更小了。
當然,隨著請求數量的增加,伺服器負載也不斷增加,解析和執行每個ASP頁面就有相應的代價。應儘可能壓縮ASP解譯器的工作量。下面是一些有用的提示。
(1) 避免在同一頁面上混用指令碼語言
如果同一頁面上有幾種指令碼語言, ASP不得不一個接一個地載入多種指令碼引擎,並把相應的代碼送給相應的引擎。這將降低處理速度,增加記憶體使用量量。另外一個副作用是,假如編寫的是一個順序執行的代碼(而不是一系列從其他程式碼片段調用的函數或子程式),可能會以與它們在頁面中出現的順序不同的順序執行。
例如,下面的代碼可能不會產生所希望的結果,因為無法確保JScript代碼的結果在網頁中是首先出現,或是在第三位出現。
(2) 在指令碼和其他內容中避免過多的環境切換
每當ASP遇到一個指令碼段,必須執行並把結果發到IIS,然後再次返回去解釋頁面。因此,使用Response.Write語句(只建立發往用戶端的文本,類似於Print命令列)能使頁面的效率更高。例如下面這段VBScript:
(3) 構建單獨的組件
假如在一個頁面不得不做大量的運算,或者運行一個過於複雜的指令碼,通常的好辦法是構建一個組件,並安裝在Web伺服器上。組件通常是編譯過的可執行代碼,相對於解釋ASP指令碼代碼,使用的效率更高。本書後面將探討構建組件的問題。