ASP講座之三:Application物件與Session對象
作者:Eve Cole
更新時間:2009-05-30 19:58:17
上一講中,我們學習了Request物件的Form資料集合、QueryString資料集合和ServerVariables資料集合。在繼續下面的學習之前,建議你先輕鬆一下,因為接下來要介紹的Application物件相對比較抽象,剛開始理解起來恐怕會不辨東西。記得:當你找不到北時,便不要過多考慮Application物件到底是什麼?還是一句老話,先學會使用它。
一、了解Application物件。為了提神,我們先看一個計數器的例程(你應該運行它以便於理解):
先編輯一個wuf16.htm檔:
<html>
<body>
記錄某個頁面的點擊數範例:<a href="wuf17.asp">wuf17.asp</a>
</body>
</html>
wuf17.asp的程式碼如下:
<% @ LANGUAGE = VBScript %>
<% 'wuf17.asp - 記錄某一頁的存取數(計數器原理)
Option Explicit
Dim CountWeb
CountWeb = Request.ServerVariables("SCRIPT_NAME")
'這樣保證每個頁面都有一個唯一的變數, 避免混亂
%>
<HTML><BODY>
<%
Response.Write CountWeb & "<Br><Br>" & vbcrlf
Application.Lock '請看講解
Application(CountWeb) = Application(CountWeb) + 1 '累加器,點選數加1
Application.UnLock
Response.Write "WEB伺服器關閉重新啟動前該頁的點選總數為: " & Application(CountWeb)
%>
</BODY></HTML>
執行這個程式時,對大部分的人來說,只有一台機器,既是Web伺服器,也是客戶端。那麼你只能想像這樣一種境況了:你的這兩個主頁檔案放在很遠的Web伺服器上,而如潮水般的國內外用戶正透過瀏覽器存取它們。每個使用者點擊一次,Application(CountWeb) 的值就會加1,只要存放檔案wuf17.asp的伺服器沒有關閉,Application(CountWeb)就會一直累積下去。但是注意,如果伺服器關閉後重啟,則Application(CountWeb)將重新從0開始計數(我暈,我說我的頁面訪問數怎麼老是一位數)。為了避免這種永遠從零開始的計數情況,你必須要在伺服器關閉之前將Application(CountWeb)的值保存起來,下次需要時再取出來,就能夠順序累計下去了,具體如何做,且聽N回後分解。
接下來的問題,就是Application.Lock、UnLock是什麼意思?剛才我們做了一個假設,大量的用戶正在訪問該頁面,而每個用戶的點擊都會發生Application(CountWeb)加1,想想看,這樣不就亂套了(什麼!想不出,那肯定是你的主頁終日只有你一個人贊助),所以得有個先來後到的規則。當某一使用者造訪該頁面,需要修改Application(CountWeb)的值時,使用Lock方法加鎖,避免其他使用者修改,修改完後,再解鎖。
從上例您是否已看出,Application物件提供給所有使用者共享資訊(Application(CountWeb)),它所面向的是所有使用者(每個使用者的存取都會導致計數器加1)。 Application物件還有兩個事件,Application_OnStart事件和Application_OnEnd事件(您可千萬別暈,這只是物件導向程式語言中起步的概念),使用時語法如下:
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnEnd
'當WEB伺服器關閉時,將啟動Application_OnEnd事件
'也就是程式將執行放在這裡的程式碼
'因此伺服器關閉前我們可以在這裡將wuf17.asp中Application(CountWeb)的值
'儲存起來,如放在一個文字檔案中。
End Sub
Sub Application_OnStart
'當第一個使用者瀏覽ASP網頁時,將啟動Application_OnStart事件,而以後其他使用者瀏覽時,就不發生這一事件了
'也就是程式將執行放在這裡的程式碼
'因此可在這裡讀出儲存在文字檔中Application(CountWeb)的值。
End Sub
</SCRIPT>
下面透過一個實例來說明如何使用事件,該程式的作用是統計網站所有頁面的總點擊數。
檔案wuf18.asp的程式碼(網站內其他頁面檔案與這個檔案類似):
<% @ LANGUAGE = VBScript %>
<% Option Explicit
'站內所有頁面檔案都應包含這句話<!--#include file="wuf19.asp"-->%>
<!--#include file="wuf19.asp"-->
<HTML><BODY>
在伺服器關閉重新啟動之前網站所有頁面總點擊數: <%= Application("CountAll") %>
</BODY></HTML>
檔案wuf19.asp的程式碼:
<% ' wuf19.asp
Application.Lock
Application("CountAll") = Application("CountAll") + 1
Application.UnLock
%>
檔案wuf18.asp與wuf19.asp放在同一目錄下。檔案global.asa的程式碼:
注意:事件處理程序必須以名為「global.asa」的文字檔案存盤,而且必須放在虛擬路徑的根目錄下(一般就是與index.htm或default.htm檔案放在同一目錄下,例如:以我的機器為例,就絕對路徑而言,global.asa放在c:InetPubhome下,而wuf18.asp和wuf19.asp放在c:InetPubhomeasp下),同一虛擬路徑只允許有一個global.asa檔案存在。
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
'global.asa - wuf18.asp 在下載套件中的檔案名稱為18global.asa,使用時要改名。
Sub Application_OnStart
'當第一個使用者瀏覽網頁時,置計數器初值為0,
'而以後其他用戶瀏覽時,不再執行以下程式碼
Application.Lock
Application("CountAll") = 0
Application.UnLock
End Sub
</SCRIPT>
瀏覽wuf18.asp查看運行結果。看來,光是學會使用Application物件並不難。
二、認識Session對象。有了前面的Application物件做鋪墊,Session物件就容易多了。它與Application物件類似,只不過是僅僅用來記錄單一使用者的相關訊息,它面向單一用戶,因此我們可以使用Session物件儲存某單一使用者的資訊。
與Application物件一樣,Session物件也有兩個事件:Session_OnStart事件和Session_OnEnd事件。使用語法與Application物件類似。
值得一提的是,使用Session物件前,必須確認瀏覽器的Cookie功能已啟用(預設設定就可以了)。
下面舉一個實例,檔案global.asa的要求同上,因此上例中的global.asa將會被本例中的global.asa覆蓋。
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
' global.asa - wuf20.asp 在下載套件中檔案名稱為20global.asa
Sub Session_OnStart
Session("In") = Now '函數Now取得當前時間
End Sub
Sub Session_OnEnd
Session("Out") = Now
Application.Lock
Application("Out") = Session("Out")
Application("In") = Session("In")
Application(“Out”).UnLock
End Sub
</SCRIPT>
檔案wuf20.asp:
<%@ Language=VBScript %>
<HTML>
<BODY>
<% 'wuf20.asp
Response.Write "預設Timeout設定:" & Session.Timeout & "分鐘<Br>"
Session.Timeout = 1
Response.Write "您進入本站的時間:" & Session("In") & "<Br>"
Response.Write "請在1 分鐘後刷新本頁" & "<Br><Br>"
if Not IsEmpty(Application("Out")) then
Response.Write "您上次進入本站的時間:" & Application("In") & "<Br>"
Response.Write "您上次離開本站的時間:" & Application("Out") & "<Br>"
Response.Write "瀏覽時間(分鐘):" &_
Datediff("n",Application("In"),Application("Out")) & "<Br><Br>"
End If
if IsEmpty(Session("Out")) then
Response.Write "刷新前後Session(""Out"")的值都是空" & "<Br>"
End If
%>
</BODY>
</HTML>
當使用者第一次瀏覽網頁時,發生Session_OnStart事件,程式記錄使用者本次進入網頁的時間,而此時不會發生Session_OnEnd事件,故Application("Out")值為空,程式不會顯示瀏覽時間。
我們知道,Application物件的生存期為第一個使用者瀏覽網頁直到伺服器關閉。而Session物件的生存期為使用者第一次瀏覽網頁(會話開始)直到會話結束。那什麼時候會話結束呢?具體到本例中,Session.Timeout = 1設定會話逾時為1分鐘,即如果長達1分鐘沒有向Web伺服器提供請求,則會話逾時,導致會話結束,發生Session_OnEnd事件,程式執行Session_OnEnd內的程式碼。在這裡我們將進入和離開時間分別放入Application("In")和Application("Out"),因為會話結束後,Session物件將不復存在,這點我們在程式碼的最後做了驗證。
從這個例程,可以看出:
1. Application物件和Session物件的生存期不同。
2. Session物件是針對單一使用者的,它的值存放在客戶端,其他使用者的瀏覽對該單一使用者的Session物件沒有任何影響。單一使用者只能讀寫自己Session物件的值(如:Session("In"))。
3. 注意在Response.Write中顯示雙引號的表示方法:(""Out"")。
4. 特別提醒:該程式沒有實用性,僅供調試用(僅適用於只有一個用戶瀏覽的情況),請思考這是為什麼?答案見本文末。
提示:請注意Application物件的特性。
三、一個經典的實例:如何在網頁上顯示在線人數在下面的例子中,用Application("Online")來存放在線人數,用Application("CountAll")存放總訪問人數。
原理:當一個新使用者瀏覽網頁時,發生Session_OnStart事件,線上人數加1,訪問用戶數也加1。當某使用者離開時,會話逾時後會發生Session_OnEnd事件,線上人數減1。
Global.asa代碼如下:
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
' Global.asa - wuf21.asp
Sub Application_OnStart
Application.Lock
'在這裡讀出Application("CountAll")的初始值
Application.UnLock
End Sub
Sub Session_OnStart
Application.Lock
Application("Online") = Application("Online") + 1
Application("CountAll") = Application("CountAll") + 1
Application.UnLock
End Sub
Sub Session_OnEnd
Application.Lock
Application("Online") = Application("Online") - 1
Application.UnLock
End Sub
Sub Application_OnEnd
Application.Lock
'應該在這裡將Application("CountAll")儲存到檔案中
Application.UnLock
End Sub
</SCRIPT>
Wuf21.asp程式碼如下:
<%@ Language=VBScript %>
<HTML>
<BODY>
<%Session.Timeout = 5%>
<P>線上人數: <%= Application("Online")%></P>
<P>訪問總人數: <%= Application("CountAll")%></P>
</BODY>
</HTML>
請注意將本例程與wuf17.asp對比,後者是計算點擊數,而前者是計算訪問人數。
答:由於Applicaton物件適用於所有用戶,因此在多用戶的情況下,其他用戶的瀏覽也會改變Application(“In”)和Application(“Out”)的值。