在上一篇中作者給大家詳細(xì)介紹了兩個(gè)非常實(shí)用的 ASP 內(nèi)建對(duì)象 Application 和 Session 的使用方法。由于這兩者的 OnStart、OnEnd 事件的腳本都必須在 Global.asa 文件中聲明 , 因此,本篇將給大家詳細(xì)介紹 Global.asa 文件的使用方法。為使大家熟練掌握至今所學(xué)過(guò)的知識(shí),本篇還將舉出一個(gè) ASP 的 Chat 程序,供各位參考。
最近很多朋友來(lái)信問(wèn)我,為什么前兩期的范例程序運(yùn)行時(shí)有這樣那樣的錯(cuò)。首先,我要向大家聲明,這些程序都是我自己寫(xiě)的,在出“廠”前都經(jīng)過(guò)合格檢驗(yàn),絕無(wú)“假冒偽劣產(chǎn)品”。:) 由于程序中使用了 cookie 記錄客戶信息,所以如果你在瀏覽器中沒(méi)有設(shè)置接受 cookie 則程序?qū)⒉荒苷_\(yùn)行。另外,程序?qū)⒖蛻粜畔⒂涗浽诳蛻舳说?cookie 所使用的方法是 Response.Cookie,此語(yǔ)句必須寫(xiě)在 ASP 文件中的第一個(gè) < HTML> 標(biāo)記前,這是因?yàn)?Cookie 是作為 HTTP 傳輸?shù)念^信息的一部分發(fā)送給客戶的,如果當(dāng) HTTP 報(bào)頭信息已經(jīng)傳輸給客戶后再使用 Response.Cookie,將出現(xiàn)以下錯(cuò)誤 :“HTTP 標(biāo)題已經(jīng)寫(xiě)入到客戶瀏覽器。任何 HTTP 標(biāo)題的修改必須在寫(xiě)入頁(yè)內(nèi)容之前?!?,可能一些朋友在剪貼程序的時(shí)候沒(méi)有注意,打亂了程序的前后次序 , 或者是錯(cuò)誤的將 HTML 代碼添加在 ASP 范例程序之前,因而導(dǎo)致程序運(yùn)行出錯(cuò)。因此,我建議大家一方面在首次運(yùn)行例程的時(shí)候不要對(duì)程序進(jìn)行任何改動(dòng),盡量在看懂程序的基礎(chǔ)上逐步改進(jìn),另一方面在運(yùn)行 ASP 程序時(shí)至少要在瀏覽器中選擇可接受 Cookie,否則一旦 ASP 程序中使用了 Cookie 或 Session,它們都將無(wú)法正常運(yùn)行。
下面我來(lái)向大家介紹 Global.asa 文件的使用方法。
什么是 Global.asa 文件?它其實(shí)是一個(gè)可選文件,程序編寫(xiě)者可以在該文件中指定事件腳本,并聲明具有會(huì)話和應(yīng)用程序作用域的對(duì)象。該文件的內(nèi)容不是用來(lái)給用戶顯示的,而是用來(lái)存儲(chǔ)事件信息和由應(yīng)用程序全局使用的對(duì)象。該文件的名稱必須是 Global.asa 且必須存放在應(yīng)用程序的根目錄中。每個(gè)應(yīng)用程序只能有一個(gè) Global.asa 文件。
在 Global.asa 文件中,如果包含的腳本沒(méi)有用 < SCRIPT> 標(biāo)記封裝,或定義的對(duì)象沒(méi)有會(huì)話或應(yīng)用程序作用域,則服務(wù)器將返回錯(cuò)誤。我們可以用任何支持腳本的語(yǔ)言編寫(xiě) Global.asa 文件中包含的腳本。如果多個(gè)事件使用同一種腳本語(yǔ)言,就可以將它們組織在一組 < SCRIPT> 標(biāo)記中。
在 Global.asa 文件中聲明的過(guò)程只能從一個(gè)或多個(gè)與 Application_OnStart、Application_OnEnd、Session_OnStart 和 Session_OnEnd 事件相關(guān)的腳本中調(diào)用。在基于 ASP 的應(yīng)用程序的 ASP 頁(yè)中,它們是不可用的。如果要在應(yīng)用程序之間共享過(guò)程,可在單獨(dú)的文件中聲明這些過(guò)程,然后使用服務(wù)器端包容 (SSI) 語(yǔ)句將該文件包含在調(diào)用該過(guò)程的 ASP 程序中。通常,包含文件的擴(kuò)展名應(yīng)為 .inc。
下面是一個(gè)很標(biāo)準(zhǔn)的 Global.asa 文件 :
< SCRIPT LANGUAGE="VBScript" RUNAT="Server">
'Session_OnStart 當(dāng)客戶首次運(yùn)行 ASP 應(yīng)用程序中的任何一個(gè)頁(yè)面時(shí)運(yùn)行
'Session_OnEnd 當(dāng)一個(gè)客戶的會(huì)話超時(shí)或退出應(yīng)用程序時(shí)運(yùn)行
'Application_OnStart 當(dāng)任何客戶首次訪問(wèn)該應(yīng)用程序的首頁(yè)時(shí)運(yùn)行
'Application_OnEnd 當(dāng)該站點(diǎn)的 WEB 服務(wù)器關(guān)閉時(shí)運(yùn)行
< /SCRIPT>
< SCRIPT LANGUAGE="VBScript" RUNAT="Server">
Sub Application_OnStart
VisitorCountFilename = Server.MapPath ("/ex2") + "\VisitCount.txt"
Set FileObject = Server.CreateObject("Scripting.FileSystemObject")
Set Out= FileObject.OpenTextFile (VisitorCountFilename, 1, FALSE, FALSE)
Application("visitors") = Out.ReadLine
Application("VisitorCountFilename") = VisitorCountFilename
End Sub
'=========================================================
SUB Application_OnEnd
Set FileOutObject = Server.CreateObject("Scripting.FileSystemObject")
Set Out= FileOutObject.CreateTextFile (Application("VisitorCountFilename"), TRUE,FALSE)
Out.WriteLine(application("visitors"))
End Sub
'=========================================================Sub Session_OnStart
Session.Timeout = 5
Application("visitors") = Application("visitors") + 1
Session("ID")=Session.SessionID
End Sub
< /SCRIPT>
在這個(gè) Global.asa 程序中,涉及到了 ASP 的 File Access 組件,它可以提供用于訪問(wèn)文件系統(tǒng)的方法、屬性和集合。這將在以后 ASP 的組件中進(jìn)行展開(kāi)討論。在這里,它起到了在服務(wù)器上創(chuàng)建新文件并對(duì)文件進(jìn)行寫(xiě)操作的作用。這其實(shí)是一個(gè) ASP 頁(yè)面訪問(wèn)記數(shù)器應(yīng)用程序的 Global 文件,首先當(dāng)客戶首次訪問(wèn)該應(yīng)用程序的首頁(yè)時(shí) , 過(guò)程 Application_OnStart 定義了在服務(wù)器上指定的虛擬目錄下新建一個(gè) VisitCount.txt 的文本文件,并將文件的路徑和內(nèi)容保存在應(yīng)用程序級(jí)的變量中。而當(dāng)任何一個(gè)客戶訪問(wèn) ASP 應(yīng)用程序中的任何一個(gè)頁(yè)面時(shí),過(guò)程 Session_OnStart 定義將應(yīng)用程序級(jí)的變量 visitors 的值自動(dòng)加一。這樣,每當(dāng)有客戶訪問(wèn)頁(yè)面時(shí),變量 visitors 都將自動(dòng)加一,以起到統(tǒng)計(jì)點(diǎn)擊率的作用。由于變量 visitors 的值是存儲(chǔ)在系統(tǒng)內(nèi)存之中,所以如果服務(wù)器關(guān)閉或重新啟動(dòng),存儲(chǔ)在變量中的數(shù)據(jù)將自動(dòng)丟失,所以通過(guò)定義過(guò)程 Application_OnEnd,在服務(wù)器關(guān)閉或重啟之前將數(shù)據(jù)寫(xiě)入事先建立的文本文件之中,這樣就能確保當(dāng)服務(wù)器再次啟動(dòng)時(shí),Application_OnStart 過(guò)程可以從 VisitCount.txt 文件中讀取以前的統(tǒng)計(jì)數(shù)。
經(jīng)過(guò)這段時(shí)間的學(xué)習(xí),相信大家已經(jīng)能夠比較熟練的運(yùn)用我們所學(xué)過(guò)的這些 ASP 內(nèi)建對(duì)象來(lái)編寫(xiě)一些較簡(jiǎn)單的 ASP 應(yīng)用程序,可別小看你現(xiàn)在所掌握的這些 ASP 基本知識(shí)哦 ! 其實(shí)你已經(jīng)能夠開(kāi)發(fā)一些簡(jiǎn)單但實(shí)用的 ASP 應(yīng)用程序了。下面我就舉一個(gè)非常簡(jiǎn)單的 ASP WEB 聊天室程序,你會(huì)發(fā)覺(jué)寫(xiě)聊天室原來(lái)是一件這么容易、輕松的事。可能朋友們已經(jīng)在一些雜志上看到過(guò) ASP 聊天程序的編寫(xiě)方法,但作者在這里自己寫(xiě)了一個(gè)更簡(jiǎn)單的程序,僅僅使用了一個(gè) .asp 文件。請(qǐng)將以下代碼剪貼到記事簿并保存為 chat.asp。
< %@ Language=VBScript %>
< %
Response.Buffer=true ' 設(shè)置輸出緩存,用于顯示不同頁(yè)面。
On error resume next ' 忽略程序出錯(cuò)部分
If Request.ServerVariables("Request_Method")="GET" then
' 判斷客戶是以什么方式請(qǐng)求 WEB 頁(yè)面
'------------------------
' 客戶登陸界面
'------------------------
%>
< form method="POST" action="chat.asp">< p>
< input type="text" name="nick" size="20" value="nick" style="background-color: rgb(192,192,192)">< br>
< input type="submit" value=" 進(jìn)入聊天室 " name="B1" style="color: rgb(255,255,0); font-size: 9pt; background-color: rgb(0,128,128)">
< p>< input type="hidden" name="log" size="20" value="1">< br>< /p>
< /form>
< %
Response.End ' 結(jié)束程序的處理
Else
Response.clear ' 清空緩存中的內(nèi)容
dim talk
If Request.Form("nick")<>"" then
' 判斷客戶是是否在聊天界面中
Session("nick")=Request.Form("nick")
End If
'------------------------'
客戶聊天界面
'------------------------
%>
< form method="POST" action="chat.asp" name=form1> < p>< %=Session("nick")%> 說(shuō)話:< input type="text" name="talk" size="50">< br>
< input type="submit" value=" 提交 " name="B1">
< input type="reset" value=" 取消 " name="B2">< /p>
< /form>
< A HREF="/asptest/shusheng/chat.asp"> 離開(kāi) < /a>< br>< br>
< %
If Request.Form("log")<>1 then
If trim(Request.Form("talk"))="" then
' 判斷用戶是否沒(méi)有輸入任何內(nèi)容
talk=Session("nick")&" 沉默是金。"
Else
talk=trim(Request.Form("talk"))
' 去掉字符后的空格
End If
Application.lock
Application("show")="< table border='0' cellpadding='0' cellspacing='0' width='85%' >< tr>< td width='100%' bgcolor='#C0C0C0'>< /td>< /tr>< tr>< td width='100%'>< font color='#0000FF'> 來(lái)自 "Request.ServerVariables("remote_addr")&" 的 "Session("nick")&time&" 說(shuō):< /font>"&talk&"< /td>< /tr>< tr>< td width='100%' bgcolor='#C0C0C0'>< /td>< /tr>< /table>< br>"&Application("show")
Application.UnLock
Response.Write Application("show")
End If
End If
%>
第一次運(yùn)行 chat.asp 程序,你首先將看到如下頁(yè)面 :
選擇你的 nick 進(jìn)入聊天室后,將看到如下頁(yè)面 :
輸入你想要說(shuō)的話,對(duì)話將出現(xiàn)在輸入框的下方,如下圖 :
下面我們來(lái)對(duì)這個(gè)聊天室程序進(jìn)行逐步的分析。
首先,由于聊天室的所有客戶都要能夠共享信息,所以不可避免的要用到具有應(yīng)用程序級(jí)變量的對(duì)象 Application,這是建立 Chat 程序的關(guān)鍵所在,所有的談話數(shù)據(jù)都存放在一個(gè)應(yīng)用程序級(jí)變量中,以便讓所有的客戶讀取。我們可以用所學(xué)過(guò)的 request 對(duì)象獲取客戶所輸入的談話,并保存在變量 talk 中 , 然后將 talk 的值存入應(yīng)用程序級(jí)變量 show 中,如下 :
< % Application("show")=talk&Application("show") %>
接下來(lái)要考慮的是當(dāng)不同的客戶同時(shí)向 Chat 應(yīng)用程序進(jìn)行操作的時(shí)候如何處理。這個(gè)問(wèn)題其實(shí)與在數(shù)據(jù)庫(kù)中的兩個(gè)用戶同時(shí)寫(xiě)入同一個(gè)記錄一樣,如果兩個(gè)用戶同時(shí)對(duì)同一個(gè)應(yīng)用程序級(jí)變量進(jìn)行寫(xiě)操作,則一個(gè)用戶所作的修改會(huì)被另一個(gè)用戶的操作所覆蓋,所以,如果對(duì) Application 對(duì)象數(shù)據(jù)的并發(fā)訪問(wèn)不采取一定措施,則會(huì)導(dǎo)致當(dāng)兩個(gè)用戶試圖同時(shí)對(duì) Asp 聊天室應(yīng)用程序提交時(shí),一個(gè)用戶的提交內(nèi)容會(huì)被另一個(gè)用戶的提交內(nèi)容所覆蓋,在被參加到會(huì)話中的任何人看到之前就消失了。為了避免這類(lèi)問(wèn)題的出現(xiàn),我們需要使用 Application 對(duì)象的 Lock 屬性來(lái)約束只允許當(dāng)前的用戶編輯或增加 Application 對(duì)象的屬性,這樣當(dāng)用戶開(kāi)始修改應(yīng)用程序級(jí)變量開(kāi)始,到 Application 對(duì)象被顯式地 Unlocked 為止,Application 對(duì)象的屬性只能被該用戶編輯,如果此時(shí)有其他用戶請(qǐng)求編輯 Application 對(duì)象,則這些用戶要排隊(duì)等待,知道應(yīng)用程序被 Unlock 為止。如下所示 :
Application.lock
Application("show")=talk&Application("show")
Application.UnLock
現(xiàn)在整個(gè)程序的核心部分你已經(jīng)了解了,下面考慮如何保存客戶信息,這里我們要用到一個(gè)會(huì)話級(jí)變量,即將客戶的 nick 保存在 Session 中。如:
Session("nick")=Request.Form("nick")
最后,我們要考慮的是如何僅在一個(gè) .asp 文件中處理各種事件 , 如 : 客戶登陸界面、客戶聊天界面。由于客戶第一次請(qǐng)求 .asp 文件時(shí),采用的是簡(jiǎn)單的 HTTP GET 方式,但是當(dāng)客戶向頁(yè)面上的表單字段中增加的數(shù)據(jù)并向自身提交表單后,.asp 文件會(huì)再次被請(qǐng)求,不過(guò)這次數(shù)據(jù)是經(jīng)過(guò) HTTP POST 方式進(jìn)行傳遞的。文件被請(qǐng)求的方式可以用兩種方法來(lái)確定。一是測(cè)試 Request.Form 集合是否包含成員,若沒(méi)有,則表明沒(méi)有發(fā)送給表單處理的數(shù)據(jù)。二是使用 Request.ServerVariables("Request_Method") 變量。如果表單是通過(guò) HTTP GET 方式被請(qǐng)求的,則這個(gè)變量會(huì)返回“GET”,如果表單被提交處理則返回“POST”。由于后一種方法對(duì)于確定文件的請(qǐng)求方式更直接,所以我們使用如下代碼進(jìn)行判斷 :
if Request.ServerVariables("Request_Method")="GET" then
由于我們?cè)O(shè)置了 ASP 緩存,所以當(dāng)程序判斷頁(yè)面請(qǐng)求方式為 GET 時(shí),程序運(yùn)行 Response.End,來(lái)結(jié)束后面的所有操作,否則則運(yùn)行 Response.clear, 清空緩存中已有的內(nèi)容,并繼續(xù)程序的運(yùn)行。這樣我們就得以用同一個(gè) .asp 文件根據(jù)不同情況給客戶顯示不同的界面。
好了,我已經(jīng)將這個(gè) ASP Chat 程序的核心部分告訴大家了,剩下的一些細(xì)節(jié)性問(wèn)題請(qǐng)各位自己讀程序吧,其實(shí)這個(gè)程序還存在很多不足之處,最大的毛病是我沒(méi)有寫(xiě)自動(dòng)刷新的功能,因此如果你在 Chat 中不說(shuō)話,那也就看不到其他客戶所說(shuō)的話了。Chat 在 Internet 中的魅力大家是知道的,其實(shí) , 用 ASP 也完全能做到同 irc 類(lèi)似的強(qiáng)大功能,當(dāng)然這就需要寫(xiě)更多的代碼,如果大家有興趣請(qǐng)寫(xiě)信給我,我將在今后的文章中逐步提升這個(gè) chat 程序的等級(jí),讓大家也過(guò)過(guò)“Oper”的隱。注:有了這個(gè) chat 程序,你就可以用來(lái)在自己的 PWS 上建一個(gè) chat 應(yīng)用程序,只要將你的 IP 地址告訴朋友,如 http://202.96.210.33/asp/chat.asp,你們就可以通過(guò)你的電腦在網(wǎng)上聊天了,很爽的,不信你試試 !