|
技术资料 > ASP技术 > ASP基础 : ASP 3.0高级编程(十一) |
ASP 3.0高级编程(十一) March 25,2004 |
第四章 服务器进程和ASP Server对象
前面的章节已经研究了ASP的一些内置对象。重点介绍的对象有Request、Response、Session和Application对象。ASP中另一个比较主要的对象为Server对象。本章重点介绍这个对象的背景知识和使用方法。
Server对象在服务器端脚本中通过实例和使用其他外部对象和组件,提供了一种扩展ASP页的功能的方法。事实上,许多人认为这个对象是ASP之所以能够流行的主要因素。引入Server对象的意义很大,这意味着ASP不必提供人们所需要的所有属性。它可调用其他应用程序和组件完成指定工作。
这也恰好符合了构建由独立的对象组成的应用程序的总体目标,而不是构建通常见到的那种耗尽硬盘空间的“可做每件事情”的巨型程序。不仅仅是在计算机的世界中,整个世界正在朝着组件和“即插即用”概念方面发展。如今,当汽车或电视机发生故障时,技师或工程师很可能会拔出有问题的部件并且插入一个新的部件,因此,汽车维护人员或电视机维修人员的工作也变成了面向对象的。
然而,IIS同样支持使用外部对象和与服务器环境进行交互作用的许多传统方法。这是一个特定的例外,这些方法并不是真正的ASP组成部分,但通常的确非常有用,并且通过Server对象的一些新特性已经与ASP很好地进行了集成。本章将简要地回顾这些传统方法,然后详细地介绍ASP Server对象。
本章的主要内容为:
· 传统的服务器端包含(SSI)指令的背景知识和使用方法。
· Server对象所要完成的任务,以及与SSI的比较。
· 如何使用Server对象实例、外部组件和应用程序。
· 如何使用Server对象执行封装的脚本或其他ASP页面。
· 如何使用Server对象管理在脚本中出现的错误。
· 如何使用Server对象完成与HTML或HTTP兼容的格式转换。
Server对象是ASP页中的错误处理过程的一部分,在IIS 5.0和ASP 3.0中是新的内容。本章介绍该对象是如何工作的。因为有单独的一章(第7章)专门讨论有关调试和错误处理方面的所有问题。所以本章只简要地讨论错误处理方法,并且仅限于Server对象直接涉及的过程。
4.1 动态页中服务器端的处理
就服务器端处理而言,ASP是产生动态Web网页的一种相对较新的技术。动态页意味着什么呢?先暂时不考虑客户端相关功能上的进展,也不讨论客户端脚本、Java Applet、动态HTML或ActiveX控件等内容。这里的动态页是专指服务器响应客户端请求产生的页面,并且根据情况每次产生的页面可能是不同的。
举个简单的例子,创建一个只包含当前日期和时间的页面。每次请求该页面时将显示一个不同的值,因为日期和时间取决于服务器的时钟,或取决于提供日期和时间的一个资源(例如一个独立的服务器或来自于互联网上一个标准时钟)。当然,实际上动态页要比这复杂得多,也许显示数据库记录的当前值或者邮件服务器上等待着的邮件消息的摘要。重要的是服务器不仅阅读一个无格式的HTML页面、或磁盘上的文本文件以及把它们发送给客户,而且,必须完成一些工作来创建该页面。
Internet服务器应用编程接口
第1章介绍了创建动态页的一些方法。传统的技术是使用与Web服务器的一个接口,它被称为Internet服务器应用编程接口(Internet Server Application Programming Interface,ISAPI)。
ISAPI可用于执行其他的应用程序,这些应用程序通过C语言风格的stdin和stdout数据流函数来读取客户端请求的值并创建Web服务器的响应。ISAPI应用程序所必须做的全部事情就是编写相应结果页面的文本和HTML,并通过stdout函数输出到Web服务器。事实上ASP DLL内部真正做的事情是更面向对象的。
IIS自开始就运行ISAPI的应用程序和脚本解释器。它提供一个特殊的解释器动态链接库,给出访问服务器的请求和响应的另一种方法,尽管受到一定的限制。它通过服务器端包含指令实现,之所以这样说,是因为它们是在服务器上执行的,并且结果包含在传送给客户端的响应中。这个特性在IIS中是通过一个名为ssinc.dll的动态链接库实现的。缺省情况下,IIS把文件扩展名为.shtml、.shtm或.stm的任意页面都映射到这个动态链接库。打开默认Web站点的Properties对话框,在Application Setting中单击Configuration按钮,可以看到这种映射,如图4-1所示:
图4-1 Application Configuration对话框
这样,带有这些被映射的文件扩展名的页面将被传送给ssinc.dll进行处理。因此,执行页面中所有的服务器端包含语句,结果(如有的话)插入到服务器的响应中,即插入到客户端接收到的页面中。
因为这些文件是映射到ssinc.dll文件而不是映射到ASP动态链接库(asp.dll)的,所以在这些页面中的所有ASP代码将被忽略并且按照原有状态传送给客户端,客户端将能够看到这些脚本。然而,在ASP 3.0版本中有一个避免这种情况的方法,稍后在讨论Server对象的Execute和Transfer方法时,研究这个方法。
4.2 服务器端的包含指令
利用服务器端的包含(SSI)语句(或者指令)能够做些什么呢?实际上不多,除非打算创建在Web服务器上运行的可执行文件,并通过stdin和stdout函数访问ISAPI。这就意味能够用C、C++或其他语言(如Delphi)等编写它们,但VB并不适合。此外,使用SSI指令能够做的事情可达到与在ASP中实现同样好的效果。许多方法中,IIS的SSI特性对使用这些特性的原有的Web网站和Web页面具有向下兼容性。
然而,可能有时会希望在站点上使用SSI而不是ASP。在IIS 5.0中,服务器端的包含指令能够比以前更加容易地集成到一个远程站点上的ASP页,它们是有用的,特别是作为执行操作系统命令或原有的CGI应用程序的一种方式。后面将会非常详细地介绍可用的指令。
#include指令是这些指令之一,它已经与ASP一起使用了一段时间了,同样也在SSI页中使用。事实上,这已经对那些不具备传统的Web开发背景的ASP开发人员带来了很多混乱。
4.2.1 不可思议的ASP #include指令
在一个ASP页中,可以使用#include指令把另一个文件的内容插入到当前的页面中:
<!-- #include file=”/scripts/usefulbits.inc” -->
这条指令读取该文件的全部内容并插入到该页中,替代<!-- #include.. -->行。这是一种非常有用的插入HTML段落的技术,可反复使用。也常用该指令来插入代码段。例如,如果有一个包含几个脚本函数(或者只是单行脚本代码)的文件同时在几个页面中使用,则可以使用#include指令将其插入到需要它的每个页中。
通过把脚本和内容分开的方法,给页面提供了一个组成层次。这意味着如果对脚本进行了修改,在客户端再次打开该页面时,脚本的修改情况自动地反映到使用包含文件的每个页面中。包含文件也是一种插入服务器特定的信息的简单方法,所以把站点转移到另一个服务器不意味着必须编辑涉及原来服务器的所有页面(明显的例子是数据库连接字符串或指定一个完整的URL或服务器名字的链接)。这可以极大地减少维护费用。
例如,可以把下面的内容作为一个包含文件,命名为connect.inc:
<%
strConnect = “SERVER=myserver;DATABASE=mydb;DRIVER={SQL Server};” _
& “UID=username;PWD=secretpassword”
%>
然后可以在任何页中使用这个文件:
<!-- #include file=”path_to_fileconnect.inc” -->
<%
…
strTheConnectionString = strConnect ‘From include file
…
%>
使用包含文件的另一种情况是有些内容需要按指定的时间间隔进行修改。例如,在Wrox Web Deverloper站点上显示书目列表的网页,它包含了一个表,其中提供了所有的封面、书名和一些按钮,如图4-2所示:
图4-2 显示书目列表的网页
这个表的HTML和文本保留在一个单独的文件中,该文件通过一条单独的#include语句包含在主页中。每次一本新书加入到该网页所基于的数据库中时,那个包含文本文件根据该数据库的情况重新创建,并作为一个文本文件写到磁盘上。
这个技术大大减少了在Web服务器和数据库服务器上的工作量,对该站点的访问者实现较快地响应。
1. 包含文件和ASP
在ASP网页(即带有.asp文件扩展名的网页)中使用的#include指令不能像一条真正的SSI指令那样进行处理,它仅是一条ASP能够识别并进行语法分析的特别指令。ssinc.dll直接用于执行SSI #include指令。然而这个由相应文件的内容替代#include指令的页面由ASP解释。
这意味着ASP对#include指令所进行的操作不实施控制。例如,可以试验以下代码:
<%
‘This will *not* work
strIncludeURL = Request.Form(“FileName”)
%>
…
<!-- #include file=”<% = strIncludeURL %>” -->
ssinc.dll将查找名为<% = strIncludeURL %>的文件,并且不可能找到,因此这段代码不会工作。
2. 包含文件的安全性
如果没有包含可执行脚本,在Web服务器上的ASP网页不能通过IIS的Web服务程序下载到一个客户端。但是,有人已经发现了偶然的安全性漏洞,比如著名的$DATA问题,所有在NTFS格式化的磁盘上保留Web内容的Web服务器都存在相应的问题。在IIS 5.0中这个问题已经得到解决。
$DATA问题的出现是因为在Windows NTFS驱动器上的所有文件都有一个缺省的“值”,即是该文件的内容,并且通过文件名加后缀“::$DATA”来指示。将其增加到一个ASP网页的URL的末尾将打乱IIS中的脚本映射关系,且允许服务器不对其中包含的脚本进行处理而不载该页面。对IIS 4.0和早期版本,有一个方法可以解决这个问题,或者可以只是增加几个映射来强制IIS正常地执行该网页:即增加对“.asp::$DATA”和“.asa::$DATA”的映射,两者都指向asp.dll文件。
包含文件的扩展各一般是.inc或.txt。如果在站点上发现一个包含文件的路径和文件名,可通过把包含文件的URL键入到浏览器的地址栏中,下载该包含文件,而不会把其作为ASP网页的一部分来执行。为防止出现这样情况,特别是在文件包含有敏感信息(诸如一个数据库链接字符串)的情况下,可能希望包含文件的扩展名为.asp。在这种情况下,如果试图下载一个包含文件,它将首先被传送到ASP,ASP将执行该文件中的所有脚本代码,并只发送出结果。如在包含文件中定义的一个链接字符串如下:
<%
strConnect = “SERVER=myserver;DATABASE=mydb;DRIVER={SQL Server};” _
& “UID=username;PWD=secretpassword”
Response.Write vbCrlf ‘Output a carriage return character
%>
客户端只能接受到单个回车符而不是脚本代码,因为该文件已经被ASP在服务器上执行了。如果不包含回车符,浏览器将挂起并等待一个响应(这并不是我们的问题,因为我们确实不打算允许用户直接访问这个文件)。
IIS 5.0和Windows的访问控制列表
在IIS 5.0中,Microsoft已经改变了Web服务器和操作系统访问服务器端包含文件的方法。
在IIS早期版本中,当ssinc.dll载入一个虚拟URL(即使用VIRTUAL = “filename”而不是FILE = “filename”)定位的一个包含文件时,将绕过Windows本身的安全性检查并忽略该文件及所存储的目录上的任何安全性设置。现在,在IIS 5.0中,运行当前ASP或SSI页面的帐号必须与对该文件和目录在Windows访问控制列表(ACL)中设置的权限相一致。如果不一致,该SSI指令运行将失败。
4.2.2 服务器端包含指令概要
除了已经讨论过的#include语句以外,还有IIS支持的五条服务器端包含指令(记住,除#include以外,这些语句不能在ASP网页中执行)。这些服务器端包含指令及说明如表4-1所示:
表4-1 服务器端包含指令及说明
指 令
说 明
#include
把一个指定文件的内容插入到将被发送给客户端的响应流中并代替该指令。例如:
<!-- #include FILE = “usefulbits.inc” -->
这条指令把名为usefulbits.inc文件的内容插入到响应中。这个文件可以由一个相对或全路径与文件名的组合描述,如FILE=”..scriptsmyscr.inc”。通过使用VIRTUAL属性,可使用一个虚拟的相对或绝对路径来描述它,例如:
<!-- #include VIRTUAL=”/mysite/ussefulbits.inc” -->
<!-- #include VIRTUAL=”../../thisbit/usefulbits.inc” -->
#config
说明在其后的指令中将用于数据、时间和文件大小以及返回给客户端的一般性的SSI错误信息的文本的格式。例如:
<!-- #config ERRMSG=”SSI Processing Error” -->
设置SSI错误信息内容为’SSI Processing Error’。
<!-- #config TIMEFMT=”%A,%B %d %Y %H:%M:%S” -->
设置由其后的SSI指令返回的日期和时间的格式。这个例子设置一个格式风格:Saturday, August 14 1999 10:34:50。可以用于格式字符串的标志的列表在附录C中给出。
<!-- #config SIZEFMT=”BYTES” -->
设置由其后的IIS指令返回的文件大小的单位。这个例子设置单位为字节。对SIZEFMT可供选择的值是“ABBREV”,指明计算值将千字节(KB)返回文件的大小
#echo
把一个HTTP环境变量的值插入到发送给客户端的响应流中并替换该指令。例如:
<!-- #echo VAR=”SERVER_NAME” -->
写出正在执行指令到该网页的服务器的名字
#exec
执行一个程序或一个服务器外壳命令,例如:
<!-- #exec CGI=”/scripts/myapp.exe?value1=this&value2=that -->
执行名为myapp.exe的CGI程序,允许传递查询字符串,程序在单独内存中执行。
<!-- #exec CMD=”cmd.exe/c iisreset/stop” -->
启动特定操作系统命令解释器(cmd.exe)并执行命令iisreset/stop。/c表示当命令结束时,命令解释器也结束。使用CMD要添加下列注册表项:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/w3SVC
/Parameters/SSIEnableCmdDirective
设置值为1,并重启动WWW服务,就允许CMD标志用于#exec指令中。值为0,则禁止使用,并防止未验证的使用
#flastmod
把一个指定的文件上一次修改的日期和时间插入到发送给客户端的响应流中并代替该指令。
例如:
<!-- #flastmod FILE=”Default.asp” -->
像#include指令一样,也可以使用虚拟路径对该文件进行定义,如:
VIRTUAL=”/mysite/usefulbits.inc”
或
VIRTUAL=”../thisbit/usefulbits.inc”
#fsize
把一个指定的文件的大小插入到发送给客户端的响应流中并代替该指令。例如:
<!-- #fsize FILE=”Default.asp” -->
象#include指令一样,也可以使用虚拟路径对该文件进行定义,如:
VIRTUAL=”/mysite/usefulbits.inc”
或
VIRTUAL=”../thisbit/usefulbits.inc”
1. IISRESET实用程序
iisreset.exe是由IIS 5.0提供的一个新的实用程序。作为一个命令行的实用程序,如果用于执行该实用程序的帐号具有管理员权限,它对于控制运行在本地或一个网络计算机上的Internet联网服务器是非常有用的。它可用于以正确的顺序停止或启动所有的服务、显示服务的状态、重新引导服务器以及允许或禁止服务的管理。例如:
iisreset /RESTART /TIMEOUT:30 /REBOOTONERROR
这将以正确的顺序停止和重新启动所有Internet服务。如果一种服务在指定的超时周期(30秒)内未能停止或重新启动,服务器将重新引导。可以用在CMD类型的#echo SSI指令中的一些开关,使该页面不能进行匿名访问并且要求用户提供在目标服务器上具有管理员权限的有效帐号的详细情况。这个实用程序的完整描述和可用的命令开关在附录C中。
2. NET STOP和NET START命令
如果用来执行实用程序net.exe的帐号具有管理员权限,它可以用来管理服务器上运行的任何服务(即可以是本地的也可以是来自其他的一个计算机)。虽然不提倡把该程序用于Internet服务(如WWW或FTP服务),但其停止和启动其他服务的功能是非常有用的。事实上,net命令同样可以用于一系列的其他网络相关命令。
语法是:
net [start | stop] service_name
例如,可以用命令net stop cisvc和net start cisvc来停止和启动Miscrosoft Indexing Service。可以用CMD类型的#echo SSI指令使该页面不能进行匿名访问并要求用户提供在目标服务器上的具有管理员权限的有效帐号的详细情况。稍后将看到一个这样的例子。
在windows 2000帮助文件中可以找到net命令的所有选项和开关的一个完整列表。从Start菜单中选择Help项,在Help窗口的Index页查找“netcommands”。
|
|
Copyright © 2001-2008 Shenzhen Hiblue Software Team All rights reserved