ASP 3.0高級編程(11)
發(fā)表時間:2024-05-22 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]第四章 服務(wù)器進程和ASP Server對象前面的章節(jié)已經(jīng)研究了ASP的一些內(nèi)置對象。重點介紹的對象有Request、Response、Session和Application對象。ASP中另一個比較主要的對象為Server對象。本章重點介紹這個對象的背景知識和使用方法。Server對象在...
第四章 服務(wù)器進程和ASP Server對象
前面的章節(jié)已經(jīng)研究了ASP的一些內(nèi)置對象。重點介紹的對象有Request、Response、Session和Application對象。ASP中另一個比較主要的對象為Server對象。本章重點介紹這個對象的背景知識和使用方法。
Server對象在服務(wù)器端腳本中通過實例和使用其他外部對象和組件,提供了一種擴展ASP頁的功能的方法。事實上,許多人認為這個對象是ASP之所以能夠流行的主要因素。引入Server對象的意義很大,這意味著ASP不必提供人們所需要的所有屬性。它可調(diào)用其他應(yīng)用程序和組件完成指定工作。
這也恰好符合了構(gòu)建由獨立的對象組成的應(yīng)用程序的總體目標,而不是構(gòu)建通常見到的那種耗盡硬盤空間的“可做每件事情”的巨型程序。不僅僅是在計算機的世界中,整個世界正在朝著組件和“即插即用”概念方面發(fā)展。如今,當(dāng)汽車或電視機發(fā)生故障時,技師或工程師很可能會拔出有問題的部件并且插入一個新的部件,因此,汽車維護人員或電視機維修人員的工作也變成了面向?qū)ο蟮摹?br>然而,IIS同樣支持使用外部對象和與服務(wù)器環(huán)境進行交互作用的許多傳統(tǒng)方法。這是一個特定的例外,這些方法并不是真正的ASP組成部分,但通常的確非常有用,并且通過Server對象的一些新特性已經(jīng)與ASP很好地進行了集成。本章將簡要地回顧這些傳統(tǒng)方法,然后詳細地介紹ASP Server對象。
本章的主要內(nèi)容為:
· 傳統(tǒng)的服務(wù)器端包含(SSI)指令的背景知識和使用方法。
· Server對象所要完成的任務(wù),以及與SSI的比較。
· 如何使用Server對象實例、外部組件和應(yīng)用程序。
· 如何使用Server對象執(zhí)行封裝的腳本或其他ASP頁面。
· 如何使用Server對象管理在腳本中出現(xiàn)的錯誤。
· 如何使用Server對象完成與HTML或HTTP兼容的格式轉(zhuǎn)換。
Server對象是ASP頁中的錯誤處理過程的一部分,在IIS 5.0和ASP 3.0中是新的內(nèi)容。本章介紹該對象是如何工作的。因為有單獨的一章(第7章)專門討論有關(guān)調(diào)試和錯誤處理方面的所有問題。所以本章只簡要地討論錯誤處理方法,并且僅限于Server對象直接涉及的過程。
4.1 動態(tài)頁中服務(wù)器端的處理
就服務(wù)器端處理而言,ASP是產(chǎn)生動態(tài)Web網(wǎng)頁的一種相對較新的技術(shù)。動態(tài)頁意味著什么呢?先暫時不考慮客戶端相關(guān)功能上的進展,也不討論客戶端腳本、Java Applet、動態(tài)HTML或ActiveX控件等內(nèi)容。這里的動態(tài)頁是專指服務(wù)器響應(yīng)客戶端請求產(chǎn)生的頁面,并且根據(jù)情況每次產(chǎn)生的頁面可能是不同的。
舉個簡單的例子,創(chuàng)建一個只包含當(dāng)前日期和時間的頁面。每次請求該頁面時將顯示一個不同的值,因為日期和時間取決于服務(wù)器的時鐘,或取決于提供日期和時間的一個資源(例如一個獨立的服務(wù)器或來自于互聯(lián)網(wǎng)上一個標準時鐘)。當(dāng)然,實際上動態(tài)頁要比這復(fù)雜得多,也許顯示數(shù)據(jù)庫記錄的當(dāng)前值或者郵件服務(wù)器上等待著的郵件消息的摘要。重要的是服務(wù)器不僅閱讀一個無格式的HTML頁面、或磁盤上的文本文件以及把它們發(fā)送給客戶,而且,必須完成一些工作來創(chuàng)建該頁面。
Internet服務(wù)器應(yīng)用編程接口
第1章介紹了創(chuàng)建動態(tài)頁的一些方法。傳統(tǒng)的技術(shù)是使用與Web服務(wù)器的一個接口,它被稱為Internet服務(wù)器應(yīng)用編程接口(Internet Server Application Programming Interface,ISAPI)。
ISAPI可用于執(zhí)行其他的應(yīng)用程序,這些應(yīng)用程序通過C語言風(fēng)格的stdin和stdout數(shù)據(jù)流函數(shù)來讀取客戶端請求的值并創(chuàng)建Web服務(wù)器的響應(yīng)。ISAPI應(yīng)用程序所必須做的全部事情就是編寫相應(yīng)結(jié)果頁面的文本和HTML,并通過stdout函數(shù)輸出到Web服務(wù)器。事實上ASP DLL內(nèi)部真正做的事情是更面向?qū)ο蟮摹?br> IIS自開始就運行ISAPI的應(yīng)用程序和腳本解釋器。它提供一個特殊的解釋器動態(tài)鏈接庫,給出訪問服務(wù)器的請求和響應(yīng)的另一種方法,盡管受到一定的限制。它通過服務(wù)器端包含指令實現(xiàn),之所以這樣說,是因為它們是在服務(wù)器上執(zhí)行的,并且結(jié)果包含在傳送給客戶端的響應(yīng)中。這個特性在IIS中是通過一個名為ssinc.dll的動態(tài)鏈接庫實現(xiàn)的。缺省情況下,IIS把文件擴展名為.shtml、.shtm或.stm的任意頁面都映射到這個動態(tài)鏈接庫。打開默認Web站點的Properties對話框,在Application Setting中單擊Configuration按鈕,可以看到這種映射,如圖4-1所示:
圖4-1 Application Configuration對話框
這樣,帶有這些被映射的文件擴展名的頁面將被傳送給ssinc.dll進行處理。因此,執(zhí)行頁面中所有的服務(wù)器端包含語句,結(jié)果(如有的話)插入到服務(wù)器的響應(yīng)中,即插入到客戶端接收到的頁面中。
因為這些文件是映射到ssinc.dll文件而不是映射到ASP動態(tài)鏈接庫(asp.dll)的,所以在這些頁面中的所有ASP代碼將被忽略并且按照原有狀態(tài)傳送給客戶端,客戶端將能夠看到這些腳本。然而,在ASP 3.0版本中有一個避免這種情況的方法,稍后在討論Server對象的Execute和Transfer方法時,研究這個方法。
4.2 服務(wù)器端的包含指令
利用服務(wù)器端的包含(SSI)語句(或者指令)能夠做些什么呢?實際上不多,除非打算創(chuàng)建在Web服務(wù)器上運行的可執(zhí)行文件,并通過stdin和stdout函數(shù)訪問ISAPI。這就意味能夠用C、C++或其他語言(如Delphi)等編寫它們,但VB并不適合。此外,使用SSI指令能夠做的事情可達到與在ASP中實現(xiàn)同樣好的效果。許多方法中,IIS的SSI特性對使用這些特性的原有的Web網(wǎng)站和Web頁面具有向下兼容性。
然而,可能有時會希望在站點上使用SSI而不是ASP。在IIS 5.0中,服務(wù)器端的包含指令能夠比以前更加容易地集成到一個遠程站點上的ASP頁,它們是有用的,特別是作為執(zhí)行操作系統(tǒng)命令或原有的CGI應(yīng)用程序的一種方式。后面將會非常詳細地介紹可用的指令。
#include指令是這些指令之一,它已經(jīng)與ASP一起使用了一段時間了,同樣也在SSI頁中使用。事實上,這已經(jīng)對那些不具備傳統(tǒng)的Web開發(fā)背景的ASP開發(fā)人員帶來了很多混亂。
4.2.1 不可思議的ASP #include指令
在一個ASP頁中,可以使用#include指令把另一個文件的內(nèi)容插入到當(dāng)前的頁面中:
<!-- #include file=”/scripts/usefulbits.inc” -->
這條指令讀取該文件的全部內(nèi)容并插入到該頁中,替代<!-- #include.. -->行。這是一種非常有用的插入HTML段落的技術(shù),可反復(fù)使用。也常用該指令來插入代碼段。例如,如果有一個包含幾個腳本函數(shù)(或者只是單行腳本代碼)的文件同時在幾個頁面中使用,則可以使用#include指令將其插入到需要它的每個頁中。
通過把腳本和內(nèi)容分開的方法,給頁面提供了一個組成層次。這意味著如果對腳本進行了修改,在客戶端再次打開該頁面時,腳本的修改情況自動地反映到使用包含文件的每個頁面中。包含文件也是一種插入服務(wù)器特定的信息的簡單方法,所以把站點轉(zhuǎn)移到另一個服務(wù)器不意味著必須編輯涉及原來服務(wù)器的所有頁面(明顯的例子是數(shù)據(jù)庫連接字符串或指定一個完整的URL或服務(wù)器名字的鏈接)。這可以極大地減少維護費用。
例如,可以把下面的內(nèi)容作為一個包含文件,命名為connect.inc:
<%
strConnect = “SERVER=myserver;DATABASE=mydb;DRIVER={SQL Server};” _
& “UID=username;PWD=secretpassword”
%>
然后可以在任何頁中使用這個文件:
<!-- #include file=”path_to_file\connect.inc” -->
<%
…
strTheConnectionString = strConnect ‘From include file
…
%>
使用包含文件的另一種情況是有些內(nèi)容需要按指定的時間間隔進行修改。例如,在Wrox Web Deverloper站點上顯示書目列表的網(wǎng)頁,它包含了一個表,其中提供了所有的封面、書名和一些按鈕,如圖4-2所示:
圖4-2 顯示書目列表的網(wǎng)頁
這個表的HTML和文本保留在一個單獨的文件中,該文件通過一條單獨的#include語句包含在主頁中。每次一本新書加入到該網(wǎng)頁所基于的數(shù)據(jù)庫中時,那個包含文本文件根據(jù)該數(shù)據(jù)庫的情況重新創(chuàng)建,并作為一個文本文件寫到磁盤上。
這個技術(shù)大大減少了在Web服務(wù)器和數(shù)據(jù)庫服務(wù)器上的工作量,對該站點的訪問者實現(xiàn)較快地響應(yīng)。
1. 包含文件和ASP
在ASP網(wǎng)頁(即帶有.asp文件擴展名的網(wǎng)頁)中使用的#include指令不能像一條真正的SSI指令那樣進行處理,它僅是一條ASP能夠識別并進行語法分析的特別指令。ssinc.dll直接用于執(zhí)行SSI #include指令。然而這個由相應(yīng)文件的內(nèi)容替代#include指令的頁面由ASP解釋。
這意味著ASP對#include指令所進行的操作不實施控制。例如,可以試驗以下代碼:
<%
‘This will *not* work
strIncludeURL = Request.Form(“FileName”)
%>
…
<!-- #include file=”<% = strIncludeURL %>” -->
ssinc.dll將查找名為<% = strIncludeURL %>的文件,并且不可能找到,因此這段代碼不會工作。
2. 包含文件的安全性
如果沒有包含可執(zhí)行腳本,在Web服務(wù)器上的ASP網(wǎng)頁不能通過IIS的Web服務(wù)程序下載到一個客戶端。但是,有人已經(jīng)發(fā)現(xiàn)了偶然的安全性漏洞,比如著名的$DATA問題,所有在NTFS格式化的磁盤上保留Web內(nèi)容的Web服務(wù)器都存在相應(yīng)的問題。在IIS 5.0中這個問題已經(jīng)得到解決。
$DATA問題的出現(xiàn)是因為在Windows NTFS驅(qū)動器上的所有文件都有一個缺省的“值”,即是該文件的內(nèi)容,并且通過文件名加后綴“::$DATA”來指示。將其增加到一個ASP網(wǎng)頁的URL的末尾將打亂IIS中的腳本映射關(guān)系,且允許服務(wù)器不對其中包含的腳本進行處理而不載該頁面。對IIS 4.0和早期版本,有一個方法可以解決這個問題,或者可以只是增加幾個映射來強制IIS正常地執(zhí)行該網(wǎng)頁:即增加對“.asp::$DATA”和“.asa::$DATA”的映射,兩者都指向asp.dll文件。
包含文件的擴展各一般是.inc或.txt。如果在站點上發(fā)現(xiàn)一個包含文件的路徑和文件名,可通過把包含文件的URL鍵入到瀏覽器的地址欄中,下載該包含文件,而不會把其作為ASP網(wǎng)頁的一部分來執(zhí)行。為防止出現(xiàn)這樣情況,特別是在文件包含有敏感信息(諸如一個數(shù)據(jù)庫鏈接字符串)的情況下,可能希望包含文件的擴展名為.asp。在這種情況下,如果試圖下載一個包含文件,它將首先被傳送到ASP,ASP將執(zhí)行該文件中的所有腳本代碼,并只發(fā)送出結(jié)果。如在包含文件中定義的一個鏈接字符串如下:
<%
strConnect = “SERVER=myserver;DATABASE=mydb;DRIVER={SQL Server};” _
& “UID=username;PWD=secretpassword”
Response.Write vbCrlf ‘Output a carriage return character
%>
客戶端只能接受到單個回車符而不是腳本代碼,因為該文件已經(jīng)被ASP在服務(wù)器上執(zhí)行了。如果不包含回車符,瀏覽器將掛起并等待一個響應(yīng)(這并不是我們的問題,因為我們確實不打算允許用戶直接訪問這個文件)。
IIS 5.0和Windows的訪問控制列表
在IIS 5.0中,Microsoft已經(jīng)改變了Web服務(wù)器和操作系統(tǒng)訪問服務(wù)器端包含文件的方法。
在IIS早期版本中,當(dāng)ssinc.dll載入一個虛擬URL(即使用VIRTUAL = “filename”而不是FILE = “filename”)定位的一個包含文件時,將繞過Windows本身的安全性檢查并忽略該文件及所存儲的目錄上的任何安全性設(shè)置,F(xiàn)在,在IIS 5.0中,運行當(dāng)前ASP或SSI頁面的帳號必須與對該文件和目錄在Windows訪問控制列表(ACL)中設(shè)置的權(quán)限相一致。如果不一致,該SSI指令運行將失敗。
4.2.2 服務(wù)器端包含指令概要
除了已經(jīng)討論過的#include語句以外,還有IIS支持的五條服務(wù)器端包含指令(記住,除#include以外,這些語句不能在ASP網(wǎng)頁中執(zhí)行)。這些服務(wù)器端包含指令及說明如表4-1所示:
表4-1 服務(wù)器端包含指令及說明
指 令
說 明
#include
把一個指定文件的內(nèi)容插入到將被發(fā)送給客戶端的響應(yīng)流中并代替該指令。例如:
<!-- #include FILE = “usefulbits.inc” -->
這條指令把名為usefulbits.inc文件的內(nèi)容插入到響應(yīng)中。這個文件可以由一個相對或全路徑與文件名的組合描述,如FILE=”..\scripts\myscr.inc”。通過使用VIRTUAL屬性,可使用一個虛擬的相對或絕對路徑來描述它,例如:
<!-- #include VIRTUAL=”/mysite/ussefulbits.inc” -->
<!-- #include VIRTUAL=”../../thisbit/usefulbits.inc” -->
#config
說明在其后的指令中將用于數(shù)據(jù)、時間和文件大小以及返回給客戶端的一般性的SSI錯誤信息的文本的格式。例如:
<!-- #config ERRMSG=”SSI Processing Error” -->
設(shè)置SSI錯誤信息內(nèi)容為’SSI Processing Error’。
<!-- #config TIMEFMT=”%A,%B %d %Y %H:%M:%S” -->
設(shè)置由其后的SSI指令返回的日期和時間的格式。這個例子設(shè)置一個格式風(fēng)格:Saturday, August 14 1999 10:34:50?梢杂糜诟袷阶址臉酥镜牧斜碓诟戒汣中給出。
<!-- #config SIZEFMT=”BYTES” -->
設(shè)置由其后的IIS指令返回的文件大小的單位。這個例子設(shè)置單位為字節(jié)。對SIZEFMT可供選擇的值是“ABBREV”,指明計算值將千字節(jié)(KB)返回文件的大小
#echo
把一個HTTP環(huán)境變量的值插入到發(fā)送給客戶端的響應(yīng)流中并替換該指令。例如:
<!-- #echo VAR=”SERVER_NAME” -->
寫出正在執(zhí)行指令到該網(wǎng)頁的服務(wù)器的名字
#exec
執(zhí)行一個程序或一個服務(wù)器外殼命令,例如:
<!-- #exec CGI=”/scripts/myapp.exe?value1=this&value2=that -->
執(zhí)行名為myapp.exe的CGI程序,允許傳遞查詢字符串,程序在單獨內(nèi)存中執(zhí)行。
<!-- #exec CMD=”cmd.exe/c iisreset/stop” -->
啟動特定操作系統(tǒng)命令解釋器(cmd.exe)并執(zhí)行命令iisreset/stop。/c表示當(dāng)命令結(jié)束時,命令解釋器也結(jié)束。使用CMD要添加下列注冊表項:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/w3SVC
/Parameters/SSIEnableCmdDirective
設(shè)置值為1,并重啟動WWW服務(wù),就允許CMD標志用于#exec指令中。值為0,則禁止使用,并防止未驗證的使用
#flastmod
把一個指定的文件上一次修改的日期和時間插入到發(fā)送給客戶端的響應(yīng)流中并代替該指令。
例如:
<!-- #flastmod FILE=”Default.asp” -->
像#include指令一樣,也可以使用虛擬路徑對該文件進行定義,如:
VIRTUAL=”/mysite/usefulbits.inc”
或
VIRTUAL=”../thisbit/usefulbits.inc”
#fsize
把一個指定的文件的大小插入到發(fā)送給客戶端的響應(yīng)流中并代替該指令。例如:
<!-- #fsize FILE=”Default.asp” -->
象#include指令一樣,也可以使用虛擬路徑對該文件進行定義,如:
VIRTUAL=”/mysite/usefulbits.inc”
或
VIRTUAL=”../thisbit/usefulbits.inc”
1. IISRESET實用程序
iisreset.exe是由IIS 5.0提供的一個新的實用程序。作為一個命令行的實用程序,如果用于執(zhí)行該實用程序的帳號具有管理員權(quán)限,它對于控制運行在本地或一個網(wǎng)絡(luò)計算機上的Internet聯(lián)網(wǎng)服務(wù)器是非常有用的。它可用于以正確的順序停止或啟動所有的服務(wù)、顯示服務(wù)的狀態(tài)、重新引導(dǎo)服務(wù)器以及允許或禁止服務(wù)的管理。例如:
iisreset /RESTART /TIMEOUT:30 /REBOOTONERROR
這將以正確的順序停止和重新啟動所有Internet服務(wù)。如果一種服務(wù)在指定的超時周期(30秒)內(nèi)未能停止或重新啟動,服務(wù)器將重新引導(dǎo)?梢杂迷贑MD類型的#echo SSI指令中的一些開關(guān),使該頁面不能進行匿名訪問并且要求用戶提供在目標服務(wù)器上具有管理員權(quán)限的有效帳號的詳細情況。這個實用程序的完整描述和可用的命令開關(guān)在附錄C中。
2. NET STOP和NET START命令
如果用來執(zhí)行實用程序net.exe的帳號具有管理員權(quán)限,它可以用來管理服務(wù)器上運行的任何服務(wù)(即可以是本地的也可以是來自其他的一個計算機)。雖然不提倡把該程序用于Internet服務(wù)(如WWW或FTP服務(wù)),但其停止和啟動其他服務(wù)的功能是非常有用的。事實上,net命令同樣可以用于一系列的其他網(wǎng)絡(luò)相關(guān)命令。
語法是:
net [start stop] service_name
例如,可以用命令net stop cisvc和net start cisvc來停止和啟動Miscrosoft Indexing Service?梢杂肅MD類型的#echo SSI指令使該頁面不能進行匿名訪問并要求用戶提供在目標服務(wù)器上的具有管理員權(quán)限的有效帳號的詳細情況。稍后將看到一個這樣的例子。
在windows 2000幫助文件中可以找到net命令的所有選項和開關(guān)的一個完整列表。從Start菜單中選擇Help項,在Help窗口的Index頁查找“netcommands”。