2009-07-27/22:10
6.2.4 Counters组件
Counters组件能用于创建、存储、递增和检索每个计数器的值。不要把它和本章后面将要介绍的Page Counter组件混淆,Counters组件能用于支持任何种类数据的统计。
一个计数器含有一个整数值,能通过Counters组件的方法进行运算。使用Set方法设置计数器的指定值,用Get方法检索计数器中的值,使用Increment方法使计数器的值加1,使用Remove方法删除一个计数器。所有的计数器的值存储在一个名为Counters.txt的文本文件中,可在Counters.dll组件所在的目录中找到该文件。
1. Counters组件的成员
Counters组件提供了用于维护每个计数器组件中数值的四个方法,如表6-4所示:
表6-4 Counters组件方法及说明
方 法
说 明
Get(counter_name)
返回指定计数器的当前值,如果此计数器先前没有创建,道德创建并设置成0,其返回值为0
Increment(counter_name)
增加指定计数器的当前值,如果此计数器先前没有创建,首先创建并设置为1
Remove(counter_name)
删除指定的计数器
Ser(counter_name,value)
把指定计数器的值设置成参数value提供的整数值,如果此计数器先前没有创建,先创建并设定为指定值
2. 使用Counters组件
由于Counters.txt文件仅有一个所有组件实例都能访问的拷贝。因此,应该只创建单个的Counters组件实例,并且使之对Web网站的所有页面都是可用的,实现这一点的常用方法是在缺省Web站点根目录下的global.asa文件中创建一个应用程序范围的实例。
采用下面程序:
<!-- declare instance of the ASP Counters component with application-level scope
-->
<OBJECT ID="objCounters" RUNAT="Server" SCOPE="Application"
PROGID="MSWC.Counters">
</OBJECT>
可以使用Counters组件对需要完成的任务创建一个新的计数器。在下面的程序中,给出了有三项选择的调查问题,并对每一种选择的回答次数进行了统计,当使用者提交包含三项选择的窗体后,将调入这个页面。假设选项通过点击SUBMIT按钮的cmdYes、cmdNo和cmdMaybe来选择,其对应值分别是“是”、“否”和“可能”。
<% 'in VBScript”
If Request.Form("cmdYes") = "Yes" Then objCounter.Increment("Response_Yes")
If Request.Form("cmdNo") = "No" Then objCounter.Increment("Response_No")
If Request.Form("cmdMaybe") = "Maybe" Then
objCounter.Increment("Response_Maybe")
%>
如果这是第一次收到一个指定的响应,程序将创建一个新的计数器并自动初始化为1。
计数器在使用范围上没有限制,因为Counters对象创建在文件global.asa中,这意味着在虚拟应用程序或Web网站中创建的任何一个页面中都是可用的,所以这个“调查计数器”可用在应用程序的任何页面上,记住单个的Counters对象能提供所需的许多独立计数器,不需要创建很多Counters对象实例。
在前面的Ad Rotator组件页面示例中,研究了如何使用Counters组件存储每个广告主的点击次数,也可以在页面中使用Counters组件的Get方法显示当前值。
Wrox Press: <B><% = objCounters.Get("wrox") %></B><BR>
Stonebroom: <B><% = objCounters.Get("stonebroom") %></B><BR>
Xtras: <B><% = objCounters.Get("xtras") %></B><BR>
ComponentSource: <B><% = objCounters.Get("compsrc") %></B><BR>
Four CDs: <B><% = objCounters.Get("fourcds") %></B><BR>
Lunar: <B><% = objCounters.Get("lunar") %></B><BR>
每次加载页面时,都自动更新计数器的当前值。然而页面也包含有一些控件能调用Counters组件的其他两个方法,即删除一个计数器(相当于将其设置为0)和将计数器设置成一个指定数值,如图6-6所示:
图6-6 Counters组件的使用演示
这些控件在一个<FORM>上,点击任何一个小的空白按钮时,此窗体便提交给同一个页面,方法与本章中的所有页面所用的几乎一样。下面的程序是为Remove方法创建控件的HTML代码。
<FORM ACTION="<% = Request.ServerVariables("SCRIPT_NAME") %>" METHOD="POST">
<INPUT TYPE="SUBMIT" NAME="cmdRemove" VALUE=" ">
Counter.Remove ("
<SELECT NAME="lstRemove" SIZE="1">
<OPTION VALUE="wrox">Wrox Press</OPTION>
<OPTION VALUE="stonebroom">Stonebroom</OPTION>
<OPTION VALUE="xtras">Xtras</OPTION>
<OPTION VALUE="compsrc">ComponentSource</OPTION>
<OPTION VALUE="fourcds">Four CDs</OPTION>
<OPTION VALUE="lunar">Lunar</OPTION>
</SELECT> ")<P>
…
</FORM>
当载入页面时,通过检查Request.Form集合查看点击的按钮,如果找到了某个按钮,将运行代码的相应部分。在点击Remove按钮的情况下,相应的代码是:
If Len(Request.Form("cmdRemove")) Then
strCounterName = Request.Form("lstRemove") 'get the counter name
objCounters.Remove strCounterName
Response.Write "Removed counter '<B>" & strCounterName & "</B>'.<P>"
End If
对于Set方法,情况类似,但不仅仅需要从文本框中读取新值,而且在调用Set方法之前,检查文本框中的值是否是有效值。
If Len(Request.Form("cmdSet")) Then
strCounterName = Request.Form("lstSet") 'get the counter name
strNewValue = Request.Form("txtSet") 'get the new value
If IsNumeric(strNewValue) Then 'if it can be converted to a number
intNewValue = CInt(strNewValue) '… then convert it
objCounters.Set strCounterName, intNewValue
Response.Write "Set counter '<B>" & strCounterName & _
"</B>' to <B>" & strNewValue & "</B>.<P>"
Else
Response.Write "<B>'" & strNewValue & "</B>' is not a valid number.<P>"
End If
End If
使用页面中的按钮调用Counters对象的方法时,重新载入时会在页面顶端看到一段信息和计数器中的新值,如图6-7所示:
图6-7 调用Counters对象的方法重新载入页面
6.2.5 Browser Capabilities组件
创建各种Web网页时面临的问题之一是,不仅仅使用ASP技术创建动态网页,而且能够使用HTML元素和其他客户端技术,像Java Applets、ActiveX控件以及最近出现的HTML元素。需要意识到的是,一些访问者若使用了恰好不支持它们的浏览器,那么对于精心编制的网页,访问者看到的可能是文本、图像的杂乱组合,甚至更糟糕的还有相应工作的脚本程序代码。
这里不讨论应当如何设计支持各种不同浏览器的网页(如果想了解这方面更多的内容,可以查阅Alex Homer编写的,Wrox出版的《Professional ASP Techniques for Webmasters》一书,书号是ISN 1-861001-79-7)。然而,确实要引用某个页面时,ASP和IIS提供铁Browser Capabilities服务器组件可以用来检测浏览器所支持的相关特征。
用户请求来自服务器的页面时,浏览器传送的HTTP报头包含了正在使用的浏览器的细节。在HTTP-speak(它被称为用户代理字符串)中,定义了浏览器的名称、版本、操作系统及其兼容性。Browser Capabilities组件在自己的配置文件中查找这个字符串,并采用许多与浏览器特征等同的特性。因此,在网页运行的任何时候,Browser Capabilities组件能够提供支持或不支持某个特性的细节。
在ASP 3.0版本中,Browser Capabilities组件增加了一个新特性。在ASP页面中包含METADATA指令,指示组件从浏览器中取出一个cookie,并把其包含的任意值添加到当前的组件实例中作为新属性。这提供了一种方法,从浏览器收集更多的用户特定的信息,而不仅仅是通常从browscap.ini文件中得到的浏览器指定的信息。了解了现有的浏览器检测特性如何工作后,再回头介绍新的METADATA技术。
1. browscap.ini文件
Browser Capabilities组件使用一个基于服务器的browscap.ini文本文件,该文本文件必须和browscap.dll组件文件处于同一目录中。browscap.ini文件包含大多数关于以前和当前浏览器的信息,并且当浏览器的用户代理字符串与文件中的指定字符串都不匹配时,将使用browscap.ini文件中的缺省部分。所以添加关于浏览器的新信息或者更新现有的信息,只需编辑browscap.ini文件。
首先看一下browscap.ini文件的格式,该文件中的所有条目都是可选的。担包括缺省部分是非常重要的。如果使用的浏览器与browscap.ini文件中的任何一个都不匹配,并且没有指定缺省浏览器设置,那么所有的特性将设置成“UNKNOWN”。
下面是browscap.ini文件的格式:
; we can add comments anywhere, prefaced by a semicolon like this
; entry for a specific browser
[HTTPUserAgentHeader]
parent = browserDefinition
property1 = value1
property2 = value 2
…
[Default Browser capability Settings]
defaultProperty1 = defaultValue1
defaultProperty2 = defaultValue2
…
[HTTPUserAgentHeader]行定义了特定浏览器的起始段,并且Parent行指明了包含浏览器更多信息的另外一个定义。下面的各行定义了我们想通过Browser Capabilities组件可获得的属性以及对于该浏览器的相应值。如果浏览器没有列在所属段中,或者尽管列出了但没有列出所有的属性,将采用Default部分所列出的属性和相应的值。
例如,这个文件包含以[IE5.0]开头的段,这个段包含有Internet Explorer 5.0的相应值,这里没有parent行,显示的(除了那些在Default部分定义的)仅是我们显示定义的属性。
[IE 5.0]
browser=IE
Version=5.0
majorver=5
minorver=0
frames=TRUE
tables=TRUE
cookies=TRUE
backgroundsounds=TRUE
vbscript=TRUE
javascript=TRUE
javaapplets=TRUE
ActiveXcontrols=TRUE
Win16=False
beta=False
AK=false
SK=false
AOL=false
Update=False
此段描述不和任何一个浏览器相匹配,因为,HTTPUserAgentHeader行仅仅是[IE 5.0]。然而,如果把[IE 5.0]作为父代,可以对浏览器添加针对IE5的定义:
[Mozilla/4.0 (compatible; MSIE 5.*; Windows 95*)]
parent=IE 5.0
version=4.0
minorver=0
platform=Win95
这样我们把[IE 5.0]指定为浏览器的父代,则显式提供的属性将代替或增加给父代定义的相应的值,但这里也假定任何其他的属性值没有显式地列在其所属段中。
为了识别非常相似的浏览器版本,在HTTPUserAgentHeader行可以使用星号通配符,如:
[Mozilla/4.0 (compatible; MSIE 5.*; Windows 95*)]
将和下面的语句相匹配:
[Mozilla/4.0 (compatible; MSIE 5.0; Windows95)]
[Mozilla/4.0 (compatible; MSIE 5.5; Windows 95 AOL)]
…
然而,只有在浏览器发送的用户代理字符串和不含“*”的HTTPUserAgentHeader不完全匹配的情况下,才采用通配符匹配。也只有当这种测试失败了,字符串才会企图和含通配符的HTTPUserAgentHeader相匹配,并且使用文件中所找到的确实匹配的第一个值。
最后,加上缺省浏览器段:
[Default Browser Capability Settings]
browser=Default
Version=0.0
majorver=#0
minorver=#0
frames=False
tables=True
cookies=False
backgroundsounds=False
vbscript=False
javascript=False
javaapplets=False
ActiveXcontrols=False
…
这里假设一种最坏的情况,浏览器几乎什么都不支持。应在此基础上定义我们实际想要使用的值。但是,如果定义了一些缺省值为True,在一个UNIX终端上使用纯文本浏览器浏览页面时,可能达不到我们所希望的效果。
维护browscap.ini文件
关闭浏览器时,更新Browscap.ini文件中相应值使其与浏览器的特性保持一致,增加一些旧的或我们关注的专用的值显然也是非常重要的。为了给用户提供方便,通常可从Microsoft Web网站上下载支持ASP的一个相当全面的browscap.ini版本或其升级版本,而CrScape Inc公司提供的browscap.ini版本经常比Microsoft Web网站上的版本更新一些。
可以在http://www.cyscape.com/browscap/上找到最新的browscap.ini版本,并且订阅一份邮件列表就可自动地收到该文件的最新版本。CrScape公司也制作一个与Microsoft Browser Capabilities组件竞争的组件,称为browserHank(本章后面将介绍),新版的browscap.ini文件也可从http://www.asptracker.com上获得。
2. 使用Browser Capabilities组件
我们已经掌握了browscap.ini文件如何提供包含有关特定浏览器信息的可定制属性,下面介绍如何使用Browser Capabilities组件。相对而言,使用Browser Capabilities组件简单一些,下面创建组件的一个实例并说明其属性。
<% 'In VBScript:
Set objBCap = Server.CreateObject("MSWC.BrowserType")
blnVBScriptOK = objBCap.vbscript 'save the result in a variable
If blnVBScriptOK Then
Response.Write "This browser supports VBScript"
Else
Response.Write "This browser doesn't support VBScript"
End If
%>
上面代码程序检查浏览器是否支持VBScript并显示一个信息,可以想象这段代码根据浏览器给出的不同响应的网页,引导用户到不同的页面。
当然,使用Browser Capabilities组件的属性可做比这更复杂的工作,一个让人喜爱的技术是根据浏览器支持的属性为网站载入不同的索引网页。如果网站有一套使用帧(frame)的页面和一套不使用帧的页面,当用户第一次访问网站时,能够检查浏览器显示帧的能力,并将其重新定位到合适的索引网页上。
3. 使用Browser Capabilities的cookie特性
新版Browser Capabilities组件增加的特性之一是提供了一种方式,以获得更多的有关调用网页的特定客户的信息.
browscap.ini文件的信息只适用于特定类型的所有浏览器,所以组件仅能报告所安装的浏览器的共同特性,例如能知道浏览器是否支持cookie,但不能知道用户是否已在浏览器“选项”对话框中关闭了cookie。
同样,使用复杂的页面设计时,最好了解用户使用的连接类型,以便能选择大小适当的图像文件传送给他们,例如用户通过局域网(而不是调制解调器)连接,则允许我们提供更加丰富的环境。如果能知道用户采用的屏幕分辨率、浏览器所用的语言、操作系统和处理器类型等参数,对于我们的设计是有帮助的。
IE 5通过使用缺省行为提供这种信息,这是客户端网页的一个元素。IE 5中的行为是新增加的,其他的浏览器不支持,这是一种对网页中的元素添加特殊功能的方法,通过STYLE属性(或CSS风格表项)和元素联系起来。特别是,IE 5提供的clientCaps行为能用于提供有关客户机和浏览器设置以及当前选项的信息。
通过创建一种元素和与之相连的clientCaps行为,能通过该元素查询到有关客户的信息。下列页面来自我们提供的示例文件(browscap_cookie.htm)正是这样做的。它首先定义了应用于<IE:clientcaps>类型的所有元素的包含clientCaps行为的风格。这是XML语法,在<HTML>标记的XLMNS属生中使用为当前网页定义的名称空间。
然而,页面browscap_cookie.htm从应用clientCaps行为的元素得到一系列值,并且建立一个包含这些值的cookie,最后,把这个cookie分配给文档的cookie属性,以便有对这个特定服务器目录的页面请求时,将它传送给服务器。
<HTML XMLNS:IE>
<HEAD>
<STYLE>
IE\:clientcaps {behavior:url(#default#clientcaps)}
</STYLE>
</HEAD>
<BODY ONLOAD="createCookie();">
<IE:clientcaps ID="objCCaps" />
<SCRIPT LANGUAGE="JavaScript">
function stopAllErrors() {
return true; // prevent display of any errors
}
function createCookie() {
window.onerror = stopAllErrors;
var strCookie = new String();
strCookie = 'width=' + objCCaps.width
+ '&height=' + objCCaps.height
+ '&availWidth=' + objCCaps.availWidth
+ '&availHeight=' + objCCaps.availHeight
+ '&bufferDepth=' + objCCaps.bufferDepth
+ '&colorDepth=' + objCCaps.colorDepth
+ '&javaEnabled=' + objCCaps.javaEnabled
+ '&cookieEnabled=' + objCCaps.cookieEnabled
+ '&connectionType=' + objCCaps.connectionType
+ '&platform=' + objCCaps.platform
+ '&cpuClass=' + objCCaps.cpuClass
+ '&systemLanguage=' + objCCaps.systemLanguage
+ '&userLanguage=' + objCCaps.userLanguage;
document.cookie = 'BrowsCap=' + strCookie;
}
</SCRIPT>
</BODY>
</HTML>
为了使用这个cookie,只需把特定的METADATA指令插入到ASP页面中。如下所示:
<!-- METADATA TYPE="Cookie" NAME="BrowsCap"
SRC="browserCapabilities/browscap_cookie.htm"-->
现在,运行这个ASP网页时,会自动把页面browscap_cookie.htm发送给客户机,客户机便运行这个行为特性,然后返回cookie,随后Browser Capabilities组件把cookie的内容添加到组件实例的可用属性的列表中,查询方法与查询browscap.ini文件创建的属性所用的方法相同。
width: <B><% = objBCap.width %></B><BR>
height: <B><% = objBCap.height %></B><BR>
…
Browser Capabilities示例网页显示两类系列数值,一类是从由browscap.ini文件决定的属性中收集的数据,另一类来自客户端cookie页面。当然,不限于仅仅收集来自客户端页面中的clientCaps行为的值,使用动态HTML技术可以查询浏览器的任何属性或者是像navigator.appName这样的传统对象属性。Browser Capabilities组件示例页面如图6-8所示:
图6-8 Browser Capabilities组件示例页面