2. IIS 5.0 ASP新功能
介绍IIS 5.0於ASP上所新增加的功能,以及详细介绍其中Server.Transfer/Execute、Server.GetLastError、支援伺服器端Scriptlet、使用cookie取得浏览器资讯、保护asp或html原始码等新功能。
ASP(Active Server Pages)3.0
在IIS伺服器端执行的指令档语言ASP(Active Server Pages),可以用来建立动态的网页内容。
Windows 2000的ASP(Active Server Pages)3.0版本提供甚麽样的新功能呢?
本章将针对IIS 5.0於ASP上所新增加的功能,详细介绍其中Server.Transfer/Execute、Server.GetLastError、支援Scriptlet、使用cookie取得浏览器资讯、保护asp或html原始码等新功能。
侦测asp程式於IIS 5.0执行
由於IIS 5.0 ASP 3.0版本新增加一些功能,asp程式必须侦测於IIS的执行版本,若於IIS 5.0执行,则善用IIS 5.0之ASP 3.0版本新增加的一些功能。
如何侦测asp程式是否於IIS 5.0执行呢?
您可使用Request.ServerVariables("SERVER_SOFTWARE")来判断是否使用IIS 5.0("Microsoft-IIS/5.0"),如下:
if Request.ServerVariables("SERVER_SOFTWARE") = "Microsoft-IIS/5.0" then
'IIS 5.0程式
else
'IIS 4.0程式
end if
2-1 IIS 5.0於ASP上新增哪些功能呢?
IIS 5.0於ASP方面新增加了几项功能,包括新的转向方法(Server.Transfer与Server.Execute方法)、新的错误处理功能(Server.GetLastError方法)、支援XML、增快无指令.asp的执行速度、调升可安装元件的效能、支援Scriptlet、使用cookie取得浏览器资讯、自动增减执行绪(executing threads)、SRC伺服器端包含功能、侦测使用者是否仍然连线、Script Encoder编码保护、内建物件的新增功能等,简介如下:
新的转向方法
新的转向方法(Server.Transfer与Server.Execute方法),直接由IIS 5.0於网站伺服器端直接转向到另一个网页,不需像Response.Redirect先传送到浏览器,再要求网站伺服器转向,如此可减少一次用户端与网站伺服器之间的来回通讯时间。
说明
有关新的转向方法部份,请参阅
2-2〈如何使用Server.Transfer/Execute呢?〉 。
新的错误处理功能
您可使用新的Server.GetLastError方法来显示有用的错误资讯。
说明
有关新的错误处理功能部份,请参阅 2-3〈如何使用Server.GetLastError呢?〉 。
支援XML
IIS 5.0的ADO 2.5,支援XML(eXtensible Markup Language),提供stream物件以将ADO之Recordset资料储存成XML格式,并暂时放置於记忆体当中。
说明
有关支援XML部份,请参阅 第叁章〈IIS 5.0与XML〉 。
增快无指令.asp的执行速度
IIS 5.0处理「无指令」的.asp档案时,执行速度上比旧版快上许多。所谓「无指令」即不含asp指令,指的是不含伺服器端程式的.asp档案。
因为处理副档名.asp须於伺服器端动态地产生内容,执行速度上比处理副档名.htm等固定资料慢上许多。於旧版IIS,即使一个副档名.asp档案只包括一些HTML码而未包括任何一行的asp指令时,执行速度也比副档名.htm慢,因此一般不会把副档名.htm改名为.asp。
IIS 5.0就可以放心地把副档名.htm改名为.asp。
调升可安装元件的效能
IIS 5.0新版的ASP将一些可安装元件(Installable Components)之执行效能加以调升。
支援伺服器端Scriptlet
ASP支援伺服器端Scriptlet(指令元件)指令技术,可以从.asp档案将Scriptlet当成COM元件的方式来呼叫。
您可以用VBScript或Jscript的语言(不需要使用Visual Basic、C++、或者Java语言来编写程式)编写Scriptlet,储存成.sct副档名,注册成为元件後,即可当成COM元件(Component Object Model)般来呼叫使用。
说明
有关Scriptlet部份,请参阅 2-4〈ASP如何支援伺服器端Scriptlet呢?〉 。
使用cookie取得浏览器资讯
现在於IIS 5.0,多了一项新的判断浏览器功能方法,方法为使用cookie储存於浏览器DHTML语法所侦测到的资讯传回IIS,以後便可透过Browser Capabilities元件得知cookie回报的浏览器资讯。
说明
有关cookie部份,请参阅 2-5〈如何使用cookie取得浏览器资讯?〉 。
自动增减执行绪(executing threads)
新版的ASP能自动增减执行绪(executing threads),当侦测到无法顺利执行要求(如被外界锁定资源)时,ASP会自动增加更多的执行绪数量,以便同时执行更多的用户端要求;当侦测到CPU的负荷过重时,ASP会自动缩减执行绪的数量。如此可降低系统来回切换执行绪的频率。
若要不启用此自动增减执行绪的功能,可以设定AspThreadGateEnabled的metabase属性。
SRC伺服器端包含功能
於伺服器端包含一个档案,除了#Include指令外,新版的ASP让您可以於HTML的<SCRIPT></SCRIPT>标记中的SRC属性来达成伺服器端的包含功能。语法如下,SRC属性可设定虚拟路径或相对路径,用RUNAT=SERVER属性来表示要伺服器端执行:
<SCRIPT LANGUAGE="VBScript" RUNAT=SERVER SRC="xxx.inc"></SCRIPT>
若须於<SCRIPT>标记内放入程式码,需多加一组<SCRIPT>标记。
侦测使用者是否仍然连线
Response.IsClientConnected侦测使用者是(True)否(False)仍然连线。
譬如:
<%
'侦测使用者是(True)否(False)仍然连线
If Response.IsClientConnected = False Then
'若未连线则取得SessionID,并加予处理
Shutdown(Session.SessionID)
End If
%>
若侦测使用者未连线,则取得SessionID,并呼叫Shutdown函数加予处理。
Script Encoder编码保护
Script Encoder程式编码工具,可以将浏览器端与伺服器端的指令加以编码,使原来的程式变成一堆无法阅读的乱码,以保护asp或html的原始码被他人所偷窥,执行时指令引擎会先自动进行解码。
说明
有关Script Encoder部份,请参阅 2-6〈如何保护asp或html原始码呢?〉 。
内建物件元件的新增功能
於内建的物件中,IIS 5.0比IIS 4.0所新增加的功能如下:
说明
有关内建物件部份,请参阅 附录B〈快速学会ASP内建物件〉 。
另外新增加Counters、Tools、Logging Utility叁个可安装的元件,如下:
说明
有关可安装的元件部份,请参阅 附录C〈快速学会ASP元件〉 。
IIS 5.0所包括的ADO 2.5对於XML新提供的功能:
说明
有关XML部份,请参阅 第叁章 〈IIS 5.0与XML〉 。
本章详细介绍其中Server.Transfer/Execute、Server.GetLastError、支援Scriptlet、使用cookie取得浏览器资讯、保护原始码等新功能,XML支援新功能将於 下一章介绍 。
2-2 如何使用Server.Transfer/Execute呢?
新的转向方法
以前在IIS 4.0网站,将一个网页转向到另一个网页的ASP转向的方法,为使用Response.Redirect指令,譬如:
<% Response.Redirect "http://www.asp.com.tw" %>
此方法需要由IIS网站先传送到浏览器,浏览器再将IIS网站要求转向到另一个网页www.asp.com.tw,如此会增加一次用户端与网站伺服器之间的来回通讯时间。那麽,为什麽不於网站伺服器端直接转向到另一个网页呢 ?
现在在IIS 5.0,可以直接由IIS 5.0於网站伺服器端直接转向到另一个网页,而不需先传送到浏览器再要求网站伺服器转向。
方法为使用IIS 5.0新增加的两个新转向方法:Server.Transfer与Server.Execute,譬如:
<% Server.Transfer("http://www.asp.com.tw") %>
Server.Transfer与Server.Execute相异之处
Server.Transfer与Server.Execute不同的地方,为执行Server.Transfer後就不会回原呼叫程式;而执行Server.Execute後仍然会继续执行原呼叫程式Server.Execute下一行的指令。
Server.Transfer与Response.Redirect比较相类似;而Server.Execute与#include用法比较相接近。
譬如execute1a.asp一行显示指令後,使用Server.Execute指令转向到另一个网页execute1b.asp:
<% Response.Write("A1(原呼叫程式)<BR>") Server.Execute "execute1b.asp" Response.Write("A2(原呼叫程式)<BR>") %>
转向後execute1b.asp只有一行显示指令:
<% Response.Write("B1(转向後)<BR>") %>
执行一行显示指令後,再执行转向後execute1b.asp显示指令,仍然会继续执行原呼叫程式Server.Execute下一行的指令。执行execute1a.asp结果如下:
若将execute1a.asp使用Server.Execute指令改变为Server.Transfer指令,如下transfer1a.asp:
<% Response.Write("A1(原呼叫程式)<BR>") Server.Transfer "execute1b.asp" Response.Write("A2(原呼叫程式)<BR>") %>
则执行後,就不会执行Server.Transfer指令後的程式了。执行transfer1a.asp结果如下:
Server.Transfer与Response.Redirect相异之处
虽然Server.Transfer与Response.Redirect都会转向,但是Server.Transfer方法会将Session和Application变数值暂时带到转向後之URL位址,Response.Redirect则不会。
譬如/iis5samp/transfer2aa.asp设定Application("test")变数值後,使用Response.Redirect指令转向到另一个网页/iis5samp2/transfer2b.asp:
<% Application("test") = "Transfer前的Application值" Response.Redirect "/iis5samp2/transfer2b.asp" %>
另一个网页transfer2b.asp仅显示Application("test")变数值:
<% Response.Write "Transfer後的Application值: " & Application("test") %>
因为转向前的iis5samp与转向後的iis5samp2属於不同的应用程式,因此iis5samp应用程式的Application("test")变数值不会传到iis5samp2应用程式,执行结果发现Application("test")为空的。执行transfer2aa.asp结果如下:
若将Response.Redirect指令改为使用Server.Transfer指令:
<% Application("test") = "是Transfer前的Application值" Server.Transfer "/iis5samp2/transfer2b.asp" %>
则因Server.Transfer方法会将Session和Application变数值带到转向後之URL位址,因此转向後执行结果Application("test")为转向前程式所设定的值。执行transfer2a.asp结果如下:
转向前程式之Session和Application变数值是暂时带到转向後的程式,不会影响转向後应用程式的Session和Application变数值。因此若再单独执行转向後的程式/iis5samp2/transfer2b.asp,并不会保留转向前程式所带来之Session和Application变数值。执行transfer2b.asp结果如下:
Server.Execute与#include相异之处
虽然Server.Execute与#include指令都是於原程式当中包含另外一个网页来执行,但是不一样的地方是#include仅将所包含的程式插入原程式当中,而Server.Execute系单独执行所包含的程式。
譬如include1a.asp使用#include指令包含另一个网页include1b.asp,第一行加入@ Transaction=Required,表示整个网页要有transaction功能:
<% @ Transaction=Required %> <!-- #include file="include1b.asp" --> <% Sub OnTransactionCommit Response.Write("原呼叫程式OnTransactionCommit副程式<BR>") End Sub Sub OnTransactionAbort Response.Write("原呼叫程式OnTransactionAbort副程式<BR>") End Sub %>
包含网页include1b.asp於第一行加入@ Transaction=Required,表示整个网页也要有transaction功能,如下:
<% @ Transaction=Required %> <% ObjectContext.SetAbort %>
因此#include仅将所包含的程式插入,造成两行的@ Transaction=Required指令,因ASP内只可使用一次@命令,执行後将显示错误。执行include1a.asp结果如下:
Server.Execute与transaction关系
Server.Execute会将转向後之URL位址之transaction结果(OnTransactionAbort和OnTransactionCommit),带回原呼叫程式而影响其transaction结果。
譬如execute2a.asp使用Response.Redirect指令转向到另一个网页execute2b.asp,第一行加入@ Transaction=Required,表示整个网页要有transaction功能:
<% @ Transaction=Required %> <% Server.Execute "execute2b.asp" Sub OnTransactionCommit Response.Write("原呼叫程式OnTransactionCommit副程式<BR>") End Sub Sub OnTransactionAbort Response.Write("原呼叫程式OnTransactionAbort副程式<BR>") End Sub %>
转向後execute2b.asp於第一行加入@ Transaction=Required,表示整个网页也要有transaction功能,并加入一行ObjectContext.SetAbort强制放弃,如下:
<% @ Transaction=Required %> <% ObjectContext.SetAbort Sub OnTransactionCommit Response.Write("转向後OnTransactionCommit副程式<BR>") End Sub Sub OnTransactionAbort Response.Write("转向後OnTransactionAbort副程式<BR>") End Sub %>
执行後,因转向後execute2b.asp之transaction结果(ObjectContext.SetAbort强制放弃导致执行转向後之OnTransactionAbort副程式),会带回原呼叫程式execute2a.asp而影响其transaction结果,所以原呼叫程式也会执行其OnTransactionAbort副程式。执行execute2a.asp结果如下:
若移除转向後execute2b.asp之ObjectContext.SetAbort程式成execute3b.asp,则转向後execute3b.asp之transaction结果(执行OnTransactionCommit副程式),会带回原呼叫程式execute3a.asp而影响其transaction结果,所以原呼叫程式也会执行其OnTransactionCommit副程式。执行execute3a.asp结果如下:
2-3 如何使用Server.GetLastError呢?
现在於IIS 5.0,可以使用新的Server.GetLastError方法来显示有用的错误资讯。
譬如执行一个错误的ASP程式如下,其中nxt应该为Next:
<% for i=1 to 1 nxt %>
执行结果显示错误讯息,如下:
每当有错误发生时,IIS预设执行500-100.asp程式,此程式中相关ASP程式如下:
Set objASPError = Server.GetLastError
'Microsoft VBScript编译阶段错误(0x800A03FC)
Response.Write Server.HTMLEncode(objASPError.Category)
If objASPError.ASPCode > "" Then Response.Write Server.HTMLEncode
(", " & objASPError.ASPCode)
Response.Write Server.HTMLEncode("(0x" & Hex(objASPError.Number)
& ")") & "<br>"
'必须要有 'Next'
If objASPError.ASPDescription > "" Then
Response.Write Server.HTMLEncode(objASPError.ASPDescription) &
"<br>"
elseIf(objASPError.Description > "") Then
Response.Write Server.HTMLEncode(objASPError.Description) &
"<br>"
end if
'/iis5samp/error1.asp, line 24
Response.Write Server.HTMLEncode(objASPError.File)
If objASPError.Line > 0 Then Response.Write ", line " & objASPError.Line
If objASPError.Column > 0 Then Response.Write ", column " & objASPError.Column
首先由Set objASPError = Server.GetLastError取得错误资讯,接着由以下属性取得相关错误资讯,如下:
您可以使用您自订的错误讯息 .asp档案来找出或显示错误。
说明
有关ASPError物件部份,请参阅附录B 〈快速学会ASP内建物件〉中
B-6〈如何使用ASPError物件呢?〉单元 。
2-4 ASP如何支援伺服器端Scriptlet呢?
ASP支援伺服器端Scriptlet(指令元件)新指令技术,您可以用VBScript或Jscript的语言(不需要使用Visual Basic、C++、或者Java语言来编写程式)编写Scriptlet,并储存成.sct副档名,注册元件成功後,即可当成COM元件(Component Object Model)般来呼叫使用。
Scriptlet可以从.asp档案或其他COM来呼叫,呼叫方式与呼叫一般COM元件相同。
如何编写Scriptlet呢 ? 首先使用 记事本 输入以下程式码,定义两个函数Add与Minus:
<SCRIPTLET> <Registration Description="Scriptlet test" ProgID="test.scr1" Version="1.00"> </Registration> <implements id=Automation type=Automation> <method name=Add> <PARAMETER name=A/> <PARAMETER name=B/> </method> <method name=Minus> <PARAMETER name=C/> <PARAMETER name=D/> </method> </implements> <SCRIPT LANGUAGE=VBScript> Function Add(A, B) Add = A + B End Function Function Minus(C, D) Minus = C - D End Function </SCRIPT> </SCRIPTLET>
接着将这个档案储存成.sct副档名,然後於 档案总管 中,在这个.sct档案上按下滑鼠右键并选取 注册 ,画面如下:
即可成功的注册为元件,画面如下:
注册成功後,asp程式如何呼叫此Scriptlet呢 ? asp程式使用Server.CreateObject("test.scr1")呼叫此Scriptlet後,即可使用所定义的两个函数Add与Minus。asp程式SCRIPTLET1.ASP如下:
<% Set obj1 = Server.CreateObject("test.scr1") Response.Write "<BR>3 + 5 = " & obj1.Add(3,5) Response.Write "<BR>10 - 5 = " & obj1.Minus(10,5) %>
执行SCRIPTLET1.ASP後之结果如下:
2-5 如何使用cookie取得浏览器资讯?
在以前的IIS版本,使用Browser Capabilities元件取得用户端浏览器的功能资讯,方法为当浏览器连线到IIS时会自动传送一个HTTP User Agent header,IIS收到後再与由其Browscap.ini对照表中找到此浏览器类型的详细资讯。
ASP程式使用Browser Capabilities元件之方法,譬如browsertype1.asp:
<% Set obj1 = Server.CreateObject("MSWC.BrowserType") Response.Write "browser = " & obj1.browser & "<BR>" Response.Write "version = " & obj1.version & "<BR>" Response.Write "frames = " & obj1.frames & "<BR>" Response.Write "tables = " & obj1.tables & "<BR>" Response.Write "BackgroundSounds = " & obj1.BackgroundSounds & "<BR>" Response.Write "vbscript = " & obj1.vbscript & "<BR>" Response.Write "javascript = " & obj1.javascript & "<BR>" Response.Write "platform = " & obj1.platform & "<BR>" Response.Write "width = " & obj1.width & "<BR>" Response.Write "height = " & obj1.height & "<BR>" Response.Write "bufferDepth= " & obj1.bufferDepth & "<BR>" Response.Write "colorDepth = " & obj1.colorDepth & "<BR>" Response.Write "cookies = " & obj1.cookies & "<BR>" %>
使用浏览器执行browsertype1.asp之结果如下,显示浏览器详细资讯:
Browser Capabilities元件方法有些缺点,譬如Browscap.ini对照表可能为未更新,或使用者於用户端浏览器更改了设定时,用户端浏览器的功能资讯就可能抓错。
现在於IIS 5.0,多了一项新的判断浏览器功能方法,方法为使用cookie储存於浏览器所侦测到的资讯传回IIS後,透过Browser Capabilities元件得知cookie回报的浏览器资讯。
首先於ASP程式cookie1.asp加一行:
<!--METADATA TYPE="Cookie" NAME="BrowsCap" SRC="cookie1.htm"-->
告诉浏览器先使用cookie1.htm中的DHTML语法侦测浏览器的资讯,传回IIS後透过Browser Capabilities元件得知cookie回报的浏览器资讯:
<% Set obj1 = Server.CreateObject("MSWC.BrowserType") %> <% Response.Write "browser = " & obj1.browser & "<BR>" Response.Write "version = " & obj1.version & "<BR>" Response.Write "frames = " & obj1.frames & "<BR>" Response.Write "tables = " & obj1.tables & "<BR>" Response.Write "BackgroundSounds = " & obj1.BackgroundSounds & "<BR>" Response.Write "vbscript = " & obj1.vbscript & "<BR>" Response.Write "javascript = " & obj1.javascript & "<BR>" Response.Write "platform = " & obj1.platform & "<BR>" Response.Write "width = " & obj1.width & "<BR>" Response.Write "height = " & obj1.height & "<BR>" Response.Write "bufferDepth= " & obj1.bufferDepth & "<BR>" Response.Write "colorDepth = " & obj1.colorDepth & "<BR>" Response.Write "cookies = " & obj1.cookies & "<BR>" %>
cookie1.htm中的DHTML语法侦测浏览器的资讯,如下:
<Script Language="JavaScript">
function window.onload()
{
body1.style.behavior = "url(#default#clientCaps)";
bcString = "browse=" + body1.browser;
bcString += "&version=" + body1.version;
bcString += "&frames=" + body1.frames;
bcString += "&tables=" + body1.tables;
bcString += "&BackgroundSounds=" + body1.BackgroundSounds;
bcString += "&vbscript=" + body1.vbscript;
bcString += "&javascript=" + body1.javascript;
bcString += "&platform=" + body1.platform;
bcString += "&width=" + body1.width;
bcString += "&height=" + body1.height;
bcString += "&bufferDepth=" + body1.bufferDepth;
bcString += "&colorDepth=" + body1.colorDepth;
bcString += "&cookies=" + body1.cookieEnabled;
document.cookie = "BrowsCap = " + bcString;
}
</SCRIPT>
</HEAD>
<BODY ID="body1">
</BODY><HTML>
使用浏览器执行cookie1.asp之结果如下,显示浏览器详细资讯:
2-6 如何保护asp或html原始码呢?
Script Encoder编码保护
Script Encoder可以将Script原始程式指令码(如VBScript、JScript)加予编码成乱码,以保护asp或html的原始码被他人所偷窥,让原始程式码不易被使用者检视或修改。
Script Encoder程式编码工具screnc.exe,可以将浏览器端与伺服器端的指令加以编码,使原来的程式变成一堆无法阅读的乱码,执行时指令引擎会先自动进行解码,无须另外的程式。
Script Encoder程式编码工具只对script编码,不对HTML编码。
可编码的程式包括:
用法:
C:> screnc test.html encode.html
编码後结果变成一堆无法阅读的乱码:
<SCRIPT LANGUAGE=VBScript.Encode> #@~^cQIAAA==@#@&@#@&@#@&i?+DP1GxPxP;DnCD+r(%+1Y`r) 9rGAcZGxUn1YrW E#@#@&7^Kxx 6a+UPr9~px1) 'hDK6'%l13wh4C2'WD9nDc:N(I9Db\Dx /W UR; VGd@#@&@#@&nJ4AAA==^#~@ </SCRIPT>
譬如transfer1a.asp原始程式指令码:
<% Response.Write("A1(原呼叫程式)<BR>") Server.Transfer "execute1b.asp" Response.Write("A2(原呼叫程式)<BR>") %>
使用screnc编码如下:
c:\iis5samp>screnc transfer1a.asp t.asp
编码後结果t.asp变成一堆无法阅读的乱码:
<%@ LANGUAGE = VBScript.Encode %> <%#@~^dwAAAA==~,@#@&"+kwW / MkO+vJ)q,P`原呼叫程式 *@!A"@*J*@#@&?D7+.RP.mxd0.Pr+an1EYnq(RC/aE@#@&)/aWxk+c DbYn`rb+~,`原呼叫程式#@!$I@*J#@#@&PxwAAA==^#~@%>
详见网站
http://msdn.microsoft.com/scripting/ 。