6.2.4 Counters組件 Counters組件能用于創(chuàng)建、存儲、遞增和檢索每個計(jì)數(shù)器的值。不要把它和本章后面將要介紹的Page Counter組件混淆,Counters組件能用于支持任何種類數(shù)據(jù)的統(tǒng)計(jì)。 一個計(jì)數(shù)器含有一個整數(shù)值,能通過Counters組件的方法進(jìn)行運(yùn)算。使用Set方法設(shè)置計(jì)數(shù)器的指定值,用Get方法檢索計(jì)數(shù)器中的值,使用Increment方法使計(jì)數(shù)器的值加1,使用Remove方法刪除一個計(jì)數(shù)器。所有的計(jì)數(shù)器的值存儲在一個名為Counters.txt的文本文件中,可在Counters.dll組件所在的目錄中找到該文件。 1. Counters組件的成員 Counters組件提供了用于維護(hù)每個計(jì)數(shù)器組件中數(shù)值的四個方法,如表6-4所示: 表6-4 Counters組件方法及說明 方 法 說 明
Get(counter_name) 返回指定計(jì)數(shù)器的當(dāng)前值,如果此計(jì)數(shù)器先前沒有創(chuàng)建,道德創(chuàng)建并設(shè)置成0,其返回值為0
Increment(counter_name) 增加指定計(jì)數(shù)器的當(dāng)前值,如果此計(jì)數(shù)器先前沒有創(chuàng)建,首先創(chuàng)建并設(shè)置為1
Remove(counter_name) 刪除指定的計(jì)數(shù)器
Ser(counter_name,value) 把指定計(jì)數(shù)器的值設(shè)置成參數(shù)value提供的整數(shù)值,如果此計(jì)數(shù)器先前沒有創(chuàng)建,先創(chuàng)建并設(shè)定為指定值
2. 使用Counters組件 由于Counters.txt文件僅有一個所有組件實(shí)例都能訪問的拷貝。因此,應(yīng)該只創(chuàng)建單個的Counters組件實(shí)例,并且使之對Web網(wǎng)站的所有頁面都是可用的,實(shí)現(xiàn)這一點(diǎn)的常用方法是在缺省Web站點(diǎn)根目錄下的global.asa文件中創(chuàng)建一個應(yīng)用程序范圍的實(shí)例。 采用下面程序: <!-- declare instance of the ASP Counters component with application-level scope --> <OBJECT ID="objCounters" RUNAT="Server" SCOPE="Application" PROGID="MSWC.Counters"> </OBJECT> 可以使用Counters組件對需要完成的任務(wù)創(chuàng)建一個新的計(jì)數(shù)器。在下面的程序中,給出了有三項(xiàng)選擇的調(diào)查問題,并對每一種選擇的回答次數(shù)進(jìn)行了統(tǒng)計(jì),當(dāng)使用者提交包含三項(xiàng)選擇的窗體后,將調(diào)入這個頁面。假設(shè)選項(xiàng)通過點(diǎn)擊SUBMIT按鈕的cmdYes、cmdNo和cmdMaybe來選擇,其對應(yīng)值分別是“是”、“否”和“可能”。 <% '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") %> 如果這是第一次收到一個指定的響應(yīng),程序?qū)?chuàng)建一個新的計(jì)數(shù)器并自動初始化為1。 計(jì)數(shù)器在使用范圍上沒有限制,因?yàn)镃ounters對象創(chuàng)建在文件global.asa中,這意味著在虛擬應(yīng)用程序或Web網(wǎng)站中創(chuàng)建的任何一個頁面中都是可用的,所以這個“調(diào)查計(jì)數(shù)器”可用在應(yīng)用程序的任何頁面上,記住單個的Counters對象能提供所需的許多獨(dú)立計(jì)數(shù)器,不需要創(chuàng)建很多Counters對象實(shí)例。 在前面的Ad Rotator組件頁面示例中,研究了如何使用Counters組件存儲每個廣告主的點(diǎn)擊次數(shù),也可以在頁面中使用Counters組件的Get方法顯示當(dāng)前值。 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> 每次加載頁面時,都自動更新計(jì)數(shù)器的當(dāng)前值。然而頁面也包含有一些控件能調(diào)用Counters組件的其他兩個方法,即刪除一個計(jì)數(shù)器(相當(dāng)于將其設(shè)置為0)和將計(jì)數(shù)器設(shè)置成一個指定數(shù)值,如圖6-6所示:
圖6-6 Counters組件的使用演示 這些控件在一個<FORM>上,點(diǎn)擊任何一個小的空白按鈕時,此窗體便提交給同一個頁面,方法與本章中的所有頁面所用的幾乎一樣。下面的程序是為Remove方法創(chuàng)建控件的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> 當(dāng)載入頁面時,通過檢查Request.Form集合查看點(diǎn)擊的按鈕,如果找到了某個按鈕,將運(yùn)行代碼的相應(yīng)部分。在點(diǎn)擊Remove按鈕的情況下,相應(yīng)的代碼是: 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方法,情況類似,但不僅僅需要從文本框中讀取新值,而且在調(diào)用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 使用頁面中的按鈕調(diào)用Counters對象的方法時,重新載入時會在頁面頂端看到一段信息和計(jì)數(shù)器中的新值,如圖6-7所示:
圖6-7 調(diào)用Counters對象的方法重新載入頁面
6.2.5 Browser Capabilities組件 創(chuàng)建各種Web網(wǎng)頁時面臨的問題之一是,不僅僅使用ASP技術(shù)創(chuàng)建動態(tài)網(wǎng)頁,而且能夠使用HTML元素和其他客戶端技術(shù),像Java Applets、ActiveX控件以及最近出現(xiàn)的HTML元素。需要意識到的是,一些訪問者若使用了恰好不支持它們的瀏覽器,那么對于精心編制的網(wǎng)頁,訪問者看到的可能是文本、圖像的雜亂組合,甚至更糟糕的還有相應(yīng)工作的腳本程序代碼。 這里不討論應(yīng)當(dāng)如何設(shè)計(jì)支持各種不同瀏覽器的網(wǎng)頁(如果想了解這方面更多的內(nèi)容,可以查閱Alex Homer編寫的,Wrox出版的《Professional ASP Techniques for Webmasters》一書,書號是ISN 1-861001-79-7)。然而,確實(shí)要引用某個頁面時,ASP和IIS提供鐵Browser Capabilities服務(wù)器組件可以用來檢測瀏覽器所支持的相關(guān)特征。 用戶請求來自服務(wù)器的頁面時,瀏覽器傳送的HTTP報(bào)頭包含了正在使用的瀏覽器的細(xì)節(jié)。在HTTP-speak(它被稱為用戶代理字符串)中,定義了瀏覽器的名稱、版本、操作系統(tǒng)及其兼容性。Browser Capabilities組件在自己的配置文件中查找這個字符串,并采用許多與瀏覽器特征等同的特性。因此,在網(wǎng)頁運(yùn)行的任何時候,Browser Capabilities組件能夠提供支持或不支持某個特性的細(xì)節(jié)。 在ASP 3.0版本中,Browser Capabilities組件增加了一個新特性。在ASP頁面中包含METADATA指令,指示組件從瀏覽器中取出一個cookie,并把其包含的任意值添加到當(dāng)前的組件實(shí)例中作為新屬性。這提供了一種方法,從瀏覽器收集更多的用戶特定的信息,而不僅僅是通常從browscap.ini文件中得到的瀏覽器指定的信息。了解了現(xiàn)有的瀏覽器檢測特性如何工作后,再回頭介紹新的METADATA技術(shù)。 1. browscap.ini文件 Browser Capabilities組件使用一個基于服務(wù)器的browscap.ini文本文件,該文本文件必須和browscap.dll組件文件處于同一目錄中。browscap.ini文件包含大多數(shù)關(guān)于以前和當(dāng)前瀏覽器的信息,并且當(dāng)瀏覽器的用戶代理字符串與文件中的指定字符串都不匹配時,將使用browscap.ini文件中的缺省部分。所以添加關(guān)于瀏覽器的新信息或者更新現(xiàn)有的信息,只需編輯browscap.ini文件。 首先看一下browscap.ini文件的格式,該文件中的所有條目都是可選的。擔(dān)包括缺省部分是非常重要的。如果使用的瀏覽器與browscap.ini文件中的任何一個都不匹配,并且沒有指定缺省瀏覽器設(shè)置,那么所有的特性將設(shè)置成“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組件可獲得的屬性以及對于該瀏覽器的相應(yīng)值。如果瀏覽器沒有列在所屬段中,或者盡管列出了但沒有列出所有的屬性,將采用Default部分所列出的屬性和相應(yīng)的值。 例如,這個文件包含以[IE5.0]開頭的段,這個段包含有Internet Explorer 5.0的相應(yīng)值,這里沒有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 此段描述不和任何一個瀏覽器相匹配,因?yàn)椋琀TTPUserAgentHeader行僅僅是[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]指定為瀏覽器的父代,則顯式提供的屬性將代替或增加給父代定義的相應(yīng)的值,但這里也假定任何其他的屬性值沒有顯式地列在其所屬段中。 為了識別非常相似的瀏覽器版本,在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)] … 然而,只有在瀏覽器發(fā)送的用戶代理字符串和不含“*”的HTTPUserAgentHeader不完全匹配的情況下,才采用通配符匹配。也只有當(dāng)這種測試失敗了,字符串才會企圖和含通配符的HTTPUserAgentHeader相匹配,并且使用文件中所找到的確實(shí)匹配的第一個值。 最后,加上缺省瀏覽器段: [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 … 這里假設(shè)一種最壞的情況,瀏覽器幾乎什么都不支持。應(yīng)在此基礎(chǔ)上定義我們實(shí)際想要使用的值。但是,如果定義了一些缺省值為True,在一個UNIX終端上使用純文本瀏覽器瀏覽頁面時,可能達(dá)不到我們所希望的效果。 維護(hù)browscap.ini文件 關(guān)閉瀏覽器時,更新Browscap.ini文件中相應(yīng)值使其與瀏覽器的特性保持一致,增加一些舊的或我們關(guān)注的專用的值顯然也是非常重要的。為了給用戶提供方便,通常可從Microsoft Web網(wǎng)站上下載支持ASP的一個相當(dāng)全面的browscap.ini版本或其升級版本,而CrScape Inc公司提供的browscap.ini版本經(jīng)常比Microsoft Web網(wǎng)站上的版本更新一些。 可以在http://www.cyscape.com/browscap/上找到最新的browscap.ini版本,并且訂閱一份郵件列表就可自動地收到該文件的最新版本。CrScape公司也制作一個與Microsoft Browser Capabilities組件競爭的組件,稱為browserHank(本章后面將介紹),新版的browscap.ini文件也可從http://www.asptracker.com上獲得。 2. 使用Browser Capabilities組件 我們已經(jīng)掌握了browscap.ini文件如何提供包含有關(guān)特定瀏覽器信息的可定制屬性,下面介紹如何使用Browser Capabilities組件。相對而言,使用Browser Capabilities組件簡單一些,下面創(chuàng)建組件的一個實(shí)例并說明其屬性。 <% '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并顯示一個信息,可以想象這段代碼根據(jù)瀏覽器給出的不同響應(yīng)的網(wǎng)頁,引導(dǎo)用戶到不同的頁面。 當(dāng)然,使用Browser Capabilities組件的屬性可做比這更復(fù)雜的工作,一個讓人喜愛的技術(shù)是根據(jù)瀏覽器支持的屬性為網(wǎng)站載入不同的索引網(wǎng)頁。如果網(wǎng)站有一套使用幀(frame)的頁面和一套不使用幀的頁面,當(dāng)用戶第一次訪問網(wǎng)站時,能夠檢查瀏覽器顯示幀的能力,并將其重新定位到合適的索引網(wǎng)頁上。 3. 使用Browser Capabilities的cookie特性 新版Browser Capabilities組件增加的特性之一是提供了一種方式,以獲得更多的有關(guān)調(diào)用網(wǎng)頁的特定客戶的信息. browscap.ini文件的信息只適用于特定類型的所有瀏覽器,所以組件僅能報(bào)告所安裝的瀏覽器的共同特性,例如能知道瀏覽器是否支持cookie,但不能知道用戶是否已在瀏覽器“選項(xiàng)”對話框中關(guān)閉了cookie。 同樣,使用復(fù)雜的頁面設(shè)計(jì)時,最好了解用戶使用的連接類型,以便能選擇大小適當(dāng)?shù)膱D像文件傳送給他們,例如用戶通過局域網(wǎng)(而不是調(diào)制解調(diào)器)連接,則允許我們提供更加豐富的環(huán)境。如果能知道用戶采用的屏幕分辨率、瀏覽器所用的語言、操作系統(tǒng)和處理器類型等參數(shù),對于我們的設(shè)計(jì)是有幫助的。 IE 5通過使用缺省行為提供這種信息,這是客戶端網(wǎng)頁的一個元素。IE 5中的行為是新增加的,其他的瀏覽器不支持,這是一種對網(wǎng)頁中的元素添加特殊功能的方法,通過STYLE屬性(或CSS風(fēng)格表項(xiàng))和元素聯(lián)系起來。特別是,IE 5提供的clientCaps行為能用于提供有關(guān)客戶機(jī)和瀏覽器設(shè)置以及當(dāng)前選項(xiàng)的信息。 通過創(chuàng)建一種元素和與之相連的clientCaps行為,能通過該元素查詢到有關(guān)客戶的信息。下列頁面來自我們提供的示例文件(browscap_cookie.htm)正是這樣做的。它首先定義了應(yīng)用于<IE:clientcaps>類型的所有元素的包含clientCaps行為的風(fēng)格。這是XML語法,在<HTML>標(biāo)記的XLMNS屬生中使用為當(dāng)前網(wǎng)頁定義的名稱空間。 然而,頁面browscap_cookie.htm從應(yīng)用clientCaps行為的元素得到一系列值,并且建立一個包含這些值的cookie,最后,把這個cookie分配給文檔的cookie屬性,以便有對這個特定服務(wù)器目錄的頁面請求時,將它傳送給服務(wù)器。 <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"--> 現(xiàn)在,運(yùn)行這個ASP網(wǎng)頁時,會自動把頁面browscap_cookie.htm發(fā)送給客戶機(jī),客戶機(jī)便運(yùn)行這個行為特性,然后返回cookie,隨后Browser Capabilities組件把cookie的內(nèi)容添加到組件實(shí)例的可用屬性的列表中,查詢方法與查詢browscap.ini文件創(chuàng)建的屬性所用的方法相同。 width: <B><% = objBCap.width %></B><BR> height: <B><% = objBCap.height %></B><BR> … Browser Capabilities示例網(wǎng)頁顯示兩類系列數(shù)值,一類是從由browscap.ini文件決定的屬性中收集的數(shù)據(jù),另一類來自客戶端cookie頁面。當(dāng)然,不限于僅僅收集來自客戶端頁面中的clientCaps行為的值,使用動態(tài)HTML技術(shù)可以查詢?yōu)g覽器的任何屬性或者是像navigator.appName這樣的傳統(tǒng)對象屬性。Browser Capabilities組件示例頁面如圖6-8所示: 圖6-8 Browser Capabilities組件示例頁面
|