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組件示例頁面