当讨论Request对象内容时,要研究的集合之一就是ServerVariables集合。这个集合包括了两种值的结合体,一种是随同页面请求从推广客户端发送到服务器的HTTP报头中的值,另外一种是由服务器在接收到请求时本身所提供的值。为显示ServerVariables集合中值的用法方法,在Request Object页面(Show_request.asp)中,点击“ServerVariables Examples”链接,打开另外一个页面,如下图所示:
下图所示窗口显示的是ServerVariables集合中一些很有用的值的一个子集。
“自引用”页面
在ServerVariables集合中返回的值包括Web服务器的详细情况和目前页面的路径信息。在任何地方创建一个页面都可用这类信息。比如创建一个“自引用”页面,此页面可以第三调用自己完成另一项任务,大家可以用以下代码:
” METHOD=”POST”>
同样的成效可以用HTTP的“script_NAME”值获得:
” METHOD=”POST”>
用元素打开一个不同页,可以用:
...
...
”>Next Page
...
即便原始页面的名字或地方发生变化,这类实例都能正常工作,由于用了目前页面的路径信息(当然,第二个例子在离别的目的页的名字发生变化时运行会失败)。
换句话说,假如为搜索引擎的子会话自动打造URL,可以采集ServerVariable的一些值:
strFullURL = http:// & Request.ServerVariables _
& “:” & Request.ServerVariables _
& Request.ServerVariables
这将创建一个完整的URL包含端口号(这样的情况下,不是标准值80)。比如,结果可能是:
http://194.74.60.254:1768/thispath/thispage.asp
测试浏览器的版本
ServerVariables集合中,另外一个有用的值是用户浏览器的用户代理字符串。在“Detecting the Browser Type”页面(browsertype.asp),用ServerVariables集合中的“HTTP_USER_AGENT”值来获得用户代理字符串,一些脚本用来分析该信息并探寻生产商名字和浏览器版本。
对IE 5.0和Navigator 4.61的搜索结果分别不同,对于其他厂商的浏览器,可以得到一个链接在Alta Vista We哔哩哔哩点自动开始搜索厂商的名字。
注意,Netscape在用户代理字符串中不提供厂商的名字,因而没办法绝对保证一个浏览器肯定是Navigator。
测试浏览器的语言
ServerVariables集合中另外一个有用的值是“HTTP_ACCEPT_LANGUAGE”,它包括了一个当浏览器安装时指定的,或硬编码进用户的区域版本的语言代码。语言代码的例子有en-us(英国、美国)、de-at(德国、澳大利亚)和es-pe(西班牙、秘鲁)。
语言代码可以是普通的且省略方言标识:比如,在大家的站点Wrox者,大量浏览者都是将en(英语)作为语言代码。
因此,可以测试语言代码并自动装载一个适合的特定区域或指定语言版本的页面。
StrLocale = Lcase,2))
Select Case strLocale
Case “en”: Response.Reprect “http://uk_site.co.uk/”
Case “de”: Response.Reprect “http://de_site.co.de/”
Case “fr”: Response.Reprect “http://fr_site.co.fr/”
‘... etc
Case Else: Response.Reprect “http://us_sitel.com/”
End Select
或者依据特定的方言,重定向页面:
strLocale = Lcase)
Select Case strLocale
Case “en-gb”: Response.Reprect “http://uk_site.co.uk/”
Case “en-us”: Response.Reprect “http://us_site.com/”
Case “es-pe”: Response.Reprect “http://es_site2.co.pe/”
‘...
Case Else: Response.Reprect “http://us_site1.com/”
End Select
其他有用的ServerVariables集合的值
可以访问和用ServerVariables集合中的任何一成员,控制ASP页面响应一个请求的方法。可以检查一个浏览者访问站点时用的是不是是缺省端口80或还是另一个。在这个例子里,探寻通过端口443的访问——这个端口提供的是避孕套接字层(Secure Socket Layer,SSI)访问(和其他的协议),且将它们重定向到一个相应的页面。
If Request.ServerVariables = “443”) Then
Response.Reprect “/securesite/default.asp” ‘Secure user
Else
Response.Reprect “/normalsite/default.asp” ‘Non-secure user
End If
倘若需要浏览者注册且由服务器验证(而不是允许他们在Web服务器的IUSER帐号下匿名访问,这个问题将在后面章节中详细讨论),可以查看用户名字,来断定正在与大家交际的用户是哪个,是不是装载页面给该用户。比如,下面的这个代码将只向名为Administrator的用户显示管理链接。
...
Change Display Configuration
Change Display Colors
Change Keyboard Configuration
Administer All Users
Administer Logon Information
...
注意ASP不填写ServerVariables集合直到你访问其中的一个成员。初次访问该集合的一个成员将使IIS得到它的全部,应只在需要时才用ServerVariables集合。
其他Request和Response方法
目前,来看一下几个用Request和Response对象的有用方法,包含:
· 连接、缓冲和页面重定向的管理。
· HTTP报头、缓存与“到期”页面的操作。
· 借助顾客证书。
· 创建定制的日志文件消息。
1. 连接、缓冲和页面重定向的管理
ASP的一个非常有用的特征就是用户可以从一个ASP网页转向到另一个网页(ASP或HTML),或另一个源文件(比如一个ZIP文件或文本文件)。这对用户来讲是透明的,事实上是浏览器做这个工作。当用Response.Reprect办法来载入一个新的网页时,事实上是发送回一个特殊的HTTP报头到顾客。此报头为:
HTTP/1.1 302 Object Moved
Location /newpath/newpage.asp
浏览器读到此报头信息,并按Location值的指示载入页面。这在功能上与在Web页中用推广客户端HTML标记相同,比如:
这带来的一个问题是,服务器与用户之间的代理服务器或许会提供它我们的包括与新页面的链接的消息,而不是直接载入新页面。而且浏览器依据厂家和版本可能做同样的工作。这就去除去假定的透明,而且对用户来讲一直收到的是错误信息,则对你的站点的访问变得比较麻烦。
在发送诸如文本或HTML等任何页面内容后,大家就不可以再用Reprect办法。然而,一个看着可以限制“代理服务器影响”的办法是,先确定没输出(包含HTTP报头)被发送到顾客。在ASP 2.0中,需要打开缓冲,然后用Clear办法来清空缓冲区:
Response.Buffer = True
‘Some conption to select the appropriate page:
If Request.ServerVariables = 1856 Then
StrNewPage = “/newpath/this_page.asp”
Else
StrNewPage = “/newpath/the_other_page.asp”
End If
Response.Clear
Response.Reprect strNewPage
在ASP 3.0中,缓冲缺省为打开,所以第一行可被忽视,但它是无害的,而且能确保大家的网页即便在ASP 2.0环境中也仍然能工作。
与其用这类的HTTP报头重定向,不如用ASP 3.0的一个新特质,它允许大家通过Server对象的Transfer办法转换为实行另一个网页,大家将在第4章进一步研究这个问题。
1) ASP页面缓冲区
正如已看到过的,IIS 5.0中ASP 3.0页面缓冲是缺省打开的,在早期的版本中是缺省关闭的。Microsoft告诉大家缓冲在IIS 5.0中提供了更有效的网页传送,这就是缓冲缺省状况被改变是什么原因。在大多数状况下,这对大家没影响。但,倘若有一个很大的网页,或一个用ASP或别的服务器端代码和组件花费肯定时间创建的网页,当其各部分完成时,大家可以分批刷新它们到顾客:
...
... Code to create first part of the page
...
Response.Flush
...
... Code to create next part of page
...
Response.Flush
...
有时可能期望在页面结束之前的某些点上停止代码的实行,可以通过调用End办法去刷新所有些目前内容到顾客并暂停任何进一步的处置过程。
...
... Code to create first part of the page
If strUserName = “” Then Response.Clear
...
... Code to create a new version of this part of the page
...
这里有两上演示缓冲和重定向的实例网页,可以从“Response Object”主页面(sow_response.asp)下载它们。第一个Response.Reprect例子网页命名为reprect.asp,它在缓冲的页面中定入一些内容,清除缓冲区,并重定向到另一个网页:
For intLoop = 1 To 1000000
Response.Write “.”
Next
Response.Clear
Response.Reprect “show_reprect.asp”
Response.End
目的页show_response.asp,做同样的工作,但重定向则是回到“Response Object”主页。由于这类网页都在缓冲区内,而且所有些输出在重定向之前需要清除,故在浏览器中没可见的输出。然而,可以通过察看浏览器的状况看到发生的每一次重定向。如下图所示:
在“Response Object”主页中,点击“Response.Flush”链接将打开第二个示例网页usebuffer.asp,它简单地遍历一个字符串的每个字符,以肯定的延迟将它们刷新到顾客,这虽是Web服务器和ASP极低效率的用法方法,但它演示了缓冲的工作方法。
下面是所需要的最小化的ASP代码,注意大家分别把每一个字符刷新到浏览器,由于不如此的话它将被存放在缓冲区中,直至网页完成:
strText = “This text has been flushed to the browser using “ & _
“Response.Flush
”
For intChar =1 To Len
For intWrite = 1 To 100000
Next
Response.Write Mid
Response.Flush
Next
2) Response.IsClientConnected属性
IsClientConnected属性在ASP 2.0中已经存在了,但却有的不靠谱。在其返回一个准确的结果之前需要发送一些输出到顾客。这一问题在ASP 3.0中已被解决。目前这一属性可被自由用。
IsClientConnected是察看用户是不是仍连到服务器和正在载入ASP创建的网页的有用方法。假如用户断开连接或停止下载,大家就不需要再浪费服务器的资源创建网页,由于缓冲区内容将被IIS遗弃。所以,对那些需要很多时间计算或资源用较多的网页来讲,值得在每一阶段都检查浏览器是不是已离线:
...
... Code to create first part of the page
...
If Response.IsClientConnected Then
Response.Flush
Else
Response.End
End If
...
... Code to create next part of page...
1. 操作HTTP报头
大家已经在几处见到ASP怎么样创建或修改在响应页面请示时被发送到顾客的HTTP报头。在Response对象中有几个属性和办法可帮助大家做到一点。下面是一些报头办法:
· 控制缓存和有效期。
· 创建状况和定制的HTTP报头。
· 指定MIME种类或内容种类。
· 添加PICS标签。
下面将简要地研究每个方面。可在“Response Object”主页(show_response.asp)上,单击有关属性名或办法名,来检查大家所说的属性和办法,如下图所示:
1. 缓存和“到期”ASP网页
用户的浏览器与他们和服务器这间的任一代理服务器,都可以缓存HTML和用ASP创建的网页。当用户随后请求页面时,浏览器就发送一个“最新修改”的请求到服务器(用一个包括缓存版本的日期的HTTP_IF_MODIFIED_SINCE报头),询问网页是不是已被修改。
若没被修改,服务器应用状况码和消息“304 Not Mopfied”来响应,浏览器将用缓存的内容而不会通过互联网下载一个副本。若已经存在已修改的版本,它就会与“200 OK”状况码和消息一道被发送出去。
1) Response.CacheContol属性
其他的一些原因也会干扰这一处置过程。然而,任一被网页用的互联网路由内的代理服务器(一般坐落于顾客机端),能被通过设置Response.CacheControl属性为Private来舍弃缓存网页。在ASP 3.0中对ASP网页这是缺省的,不需要设置。但在网页为个别访问者特别定制时特别有用。这可以阻止别的在同一互联网上的用户进入同一网页。当CacheControl的属性值被设定为Public时,允许服务器缓存网页。注意,一些代理服务器可能表现得不尽相同,或忽略或越过这个报头。
在IE4中,在代理服务器缓存可用时,大概得到一个不真实的“This page has expired”消息。大家已提供了一个网页(expiretest_form.asp),可以通过我们的代理服务器在互联网上做试验,来检查这一属性的影响。可以通过在“Response Object”主页中单击“Response. CacheControl”链接来显示这个网页。如下图所示:
这一页面提交到expiretest_result.asp网页时,可以设置Response.CacheControl属性,然后在网页中插入值和脚本被实行的时间:
<%
If Request.Form = “on” Then ‘Cache-Control check box was ticked
Response.CacheControl = “Public”
Else
Response.CacheControl = “Private”
End If
%>
...
Cache-Control is: <% = Response.CacheControl %>
Value in text box is: <% Response.Write Request.Form %>
<%
Response.Write Right,2) & “:” & Right,_
& 2) & “:” & Right,2)
%>
通过单击浏览器上的“Back”和“Forward”,能看到代码是自动实行还是用缓存的副本,如下图所示。结果随浏览器的不同而变化。
2) Response.Expires和Response.ExpiresAbsolute属性
控制缓存的网页存放时间的两个属性为Response对象的Expires和ExpriesAbsolute属性。Response.Expires概念了风页在从缓存区被遗弃前应维持有效的时间长度,以创建以来的分钟数形式表示。ExpiresAbsolute属性为到期时间设置了一个绝对的日期和时间。
大家提供一个命名为addheaders_form.asp的例子网页,用于演示怎么用这类属性。在“Response Object”主页中单击对这两种属性的链接,如下图所示:
在这一页面中,可加入自己定制的HTTP报头,并可设置一些影响响应的HTTP报头的多种属性。在“提交查看内容”按钮上单击时,页面show_headers.asp在返回的数据流中添加所选的报头,然后显示用来完成此操作的代码,显示相应的实行时间,可用来检查页面是被缓存还是被第三实行,如下图所示:
show_headers.asp网页中的代码创建和添加HTTP报头,程序如下:
<%
‘Write HTTP headers before any other output
If Request.Form = “on” Then _
Response.Expires = Request.Form
If Request.Form = “on” Then _
Response.ExpiresAbsolute = Request.Form
If Request.Form = “on” Then _
Response.AddHeader “LAST-MODIFIED”, Cstr)
If Request.Form = “on” Then _
Response.AddHeader “PRAGMA”, CStr)
If Request.Form = “on” Then _
Response.AddHeader “REFRESH”, CStr)
If Request.Form = “on” And Len) Then _
Response.AddHeader CStr), _
CStr)
If Request.Form = “on” Then _
Response.Status = Request.Form
%>
...
... Show code and execution time
...
其余部分只是显示已被实行的代码和实行时间。读者会注意到包括在网页中的定制的报头“PRAGMA”(到今天大家还没有讨论过)。一些(先前的)代理服务器用它作为网磁是不是应被缓存的指示。缺省是网页被缓冲,除非同意到HTTP报头“PRAGMA=NO-CACHE“。
2. 创建状况码和定制的HTTP报头
可用先前在实例网页中所看到的Response对象的AddHeader办法来创建我们的状况码或自己喜欢的定制的报头。这一办法需要两个参数:HTTP报头名字或一个包括其值或分配给它的值的字符串。作为一个例子,下面的代码在页面中添加REFRESH报头:
Response.AddHeader “REFRESH”, ”60;URL=newpath/newpage.asp”
这等同于顾客机端
换句话说,也可配合Status属性用AddHeader办法使浏览器载入一个新的页面:
Response.Status = “302 Object Moved”
Response.Addheader “Location”, “newpath/newpage.asp”
这等同于用Response.Reprect办法:
Response.Reprect “newpath/newpage.asp”
Response.Status属性可被用来发送一些所需要的状况消息,比如添加如下几行:
Response.Status= “401 Unauthorized”
Response.Addheader “WWW-Authenticate”, “BASIC”
强制浏览器显示一个用户名/口令对话框,然后用BASIC验证把它们发送回服务器(将在本书后续部分看到验证办法)。
3. MIME种类和内容种类
当大家想向浏览器发送一个动态创建的字符串,而且它们自己提供给浏览器时没直接指明内容种类,而是提供表示是不是是磁盘文件的扩展名时,Response.ContentType是很有用的。除非特别指定,所有ASP创建的网页缺省都为“text/type”。内容种类的标识符是MIME种类(MIME代表Multi-purpose Internet Multimepa Extension或Multi-pupose Internet Mail Extension,一般依据上下文来定)。
比如,若发送到顾客的数据注释是通过从数据库读二进制值创建的图片,就需要在发送任何内容之前添加适合的CONTENT-TYPE报头:
Response.ContentType = “image/jpeg”
倘若从一个数据库创建一个XML文件,用MIEM种类“text/xml”;并且假如正在创建一个文本文件可以在文件编辑器中显示或作为一个磁盘文件在顾客上被存储起来,用“text/text”。
4. 添加PICS卷标
Respnse.Pics属性只是添加一个PICS(Platform for Internet Content system)卷标到页面上,方法与一般用
QUOT = Chr
StrPicsLabel = “)”
Response.Pics
这段代码添加了如下的PICS卷标:
)
要得到关于PICS的更多的信息,或知道更多的概念页面内容的方法,请检索http://www.rsac.org/站点。
在Internet Service Manager中概念报头
在第1章,已经说明了怎么样在Internet Service Manage应用程序中设置每一个Web网站和IIS 5.0目录的属性,这就概念了用此站点或目录资源发送到顾客机的所有请求的HTTP报头,也就提供了用每一个网页中的ASP脚本代码设置这类属性的替代办法。
在We哔哩哔哩点或目录上右击鼠标并选择“Properties”,在其对话框的“HTTP Headers”选项卡中,可设置页面内容有效期的相对时间或绝对日期,概念定制的报头,创建PICS内容等级标签,也可以通过MIME种类映射来概念内容种类,如下图所示:
在上图中,可以看到已创建了自概念的REFRESH HTTP报头,应用于从此目录载入的所有网页。即每一分钟自动地重载(刷新)一次(对于显示棒球比赛的近期比分是很理想的,但对服务器而言负担太重了)。Custom HTTP Headers栏的Ept对话框如下图所示:
要在“MIME Map”框中添加自概念的内容种类映射,仅需在“Properties”主对话框中单击“File Types”按扭把它们添加到清单中即可,如下图所示:
当用HTTP报头开始试验时,你非常快会发现不是所有些浏览器表现都相同,很多浏览器以不一样的方法响应不一样的HTTP报头,使得靠谱地打造一个常见适用的原则有时极为困难。
2. 用顾客证书
倘若设立了一个安全的Web网站或部分内容具备安全机制的网站,可安装一个数字服务器证书,通过允许访问者用证书中的加密的细节,来验证服务器。每一次对该站点或目录的页面请求,服务器都将发送证书的一个副本,浏览器可检查这个副本以确定正在和哪个交谈。
同样,也可设置服务器,需要用户在进入网站时提供一个有效的数字证书。他们可从不少来源获得此证书,比如Verisign(http://www.verisign.com)或Thawte Consulting。读者将在第25章看到这一处置过程的细节。
这类状况都用了Request对象的ClientCertificate集合的值,本章的实例代码中,已包括了一个显示用户怎么用些集合值的一些办法的页面。
这一网页被命名为showcert.asp,而且其所做的所有就是遍历ClientCertificate集合显示其包括的所有值。可用以前常常用的简单代码来完成它,唯一的区别就是打造一个HTML表以容纳结果,并将它截为每60个字符一组。
<%
For Each keyItem In Request.ClientCertificate
StrItemValue = Request.ClientCertificate
If Len > 90 Then strItemValue = Left & “..etc.”
Response.Write “” & keyItem & “ = “ & strItemValue & “”
Next
%>
运行结果如下图所示:(因为豆豆没申请服务器证书,该图略)
用顾客证书重定向
一旦需要所有访问网站或部分网站的浏览者给出的其顾客证书,就能用其包括的信息来制作大家为此用户创建的网页。比如,可用他们的证书的Organization条目来自动使他们重定向到该网站的指定部分,使别的访问者重定向到别的地方:
If Request.ClientCertificate = “Wrox Press Inc” Then
Response.Reprect “/wrox_staff/default.asp” ‘Wrox staff site
Else
Response.Reprect “/public/Default.asp” ‘Normal public site
End If
相应地,可用Country条目来使访问者重定向到一个相应的网站:
Select Case Request.ClientCertificate
Case “UK”: Response.Reprect “http://uk_site.co.uk/”
Case “DE”: Response.Reprect “http://de_site.co.de/”
Case “FR”: Response.Reprect “http://fr_site.co.fr/”
‘... ect.
Case Else: Response.Reprect “http://us_site.com/”
End Select
3. 读写二进制数据
有两个办法提供了对从浏览器发送到服务器的HTTP数据流和从服务器返回到浏览器的数据流的二进制数据访问。Request.BinaryRead办法可得到指定要读取的字节数的参数,并返回变体种类的数组,其中包括从请求的POST段中得到的字节(比如在ASP的Form集合中数据)。下面的程序读数据的头64个字节:
varContent = Request.BinaryRead
倘若用了BinaryRead办法,将来就不可以访问ASP的Request.Form集合。同样,一旦大家使用任何方法引用了Request.Form集合,就不可以用BinaryRead办法。
把二进制数据写进ASP创建的响应流中也是可能的,可使用BinaryWrite办法。需要给其提供想写到顾客的字节的变体种类数组:
Response.BinaryWrite
这类办法都极少用,除非从一个数据库创建非HTML源才用到这类办法。用的一个实例就是从数据库读取组成图像的字节,并用BinaryWrite办法把它发送到顾客。
4. 创建定制的日志消息
倘若设置了服务器,以W3C Extended Log File Format格式将请求记录到一个文本文件,可用Response.AppendToLog办法在日志文件条目的结尾处添加一条消息字符串。若想为特定的网页存储一些值或消息,或在脚本中出现了特定的状况时,这种方法是很有用的。
比如,通过的Intranet的“stationary order”应用程序,可以记录超越特定的条目数目的雇员的部门号码:
...
If intItemCount > 25 Then
Response.AppendToLog “Large order from ‘” & strDept & department.”
End If
...
设置扩展的日志
要用AppendToLog办法,需要激活W3C Extended Log File Format日志设置。该设置办法是,进入Properties对话框中的Web Site选项卡,选中Enable Logging复选框,选择W3C Extended Log File Format并单击Properties按钮,如下图所示:
在出现的Extended Logging Properties对话框中,可选择想包含进日志文件的条目。确保选中URI Stem,不然AppendToLog办法将失败,如下图所示:
大家提供了一个试图在日志文件中写入一个条目的简单实例页面,可从Request Object主页(show_request.asp)中的AppendToLog办法链接处打开它。这一页面所做的全部工作就是创建一个包括目前日期和时间的简单字符串,然后实行AppendToLog办法:
strToAppend = “Page executed on ” & Now
Response.AppendToLog strToAppend
结果如下图所示:
小结
本章已经开始了对ASP 3.0的研究,而且大家也看到了ASP 3.0怎么样与Internet Informateion Server 5.0一同工作,以提供一个易用的、高效的创建动态Web网页和Web应用程序的办法。当然,仍有一些地方需要去研究,本章只是学习了ASP内置的两个最基本的对象。
这两个最基本的对象是Request和Response对象,允许大家访问和用作为顾客机/服务器会话一部分的值,无论用户何时从Web网站请求和载入一个网页或资源,这种会话就会进行,意味着Request对象可以提供对用户请求的全部内容的访问,同时Response对象允许创建和修改服务器发回的响应。
这类对象可以通过集合和属性揭示会话的每个部分,并提供了多个可以用来检索和修改各段的办法。倘若把它们当作分解用户请求和用相应的内容创建响应的工具,这有帮你理解到底出了什么事。这也或有助于理解各种办法怎么样影响顾客、服务器和正在创建的网页。