ASP程式寫作入門

編寫:黃自強   dd@mail.ysps.tp.edu.tw

李忠憲 shane@mail.spps.tp.edu.tw

寫在前面

  不管您是為了個人興趣,或是純粹為了工作需要來學習ASP程式設計,學習方法上是很重要的。從不斷嚐試錯誤中學習而得的經驗固然可貴,但是在學習效果上並不好。

  這裡建議的能力培養順序應該是:

  1. 熟練 html 語法(學習網頁編寫能力)

  2. 了解IIS/ASP的運作原理(系統管理能力)

  3. 了解IE4.0以上的DHTML/CSS(網頁元件物件控制能力)

  4. Java/VB 等Client端 Script( Client 端檢查/控制能力)

  5. ASP六大物件和語法及ActiveX元件使用(Server 端 Script 控制能力)

  6. 資料庫設計/分析(資料庫規劃能力)

  7. SQL語法(資料庫增刪修等管理能力)

  8. ActiveX元件設計/網頁美工設計(非必要能力,會的話更好)

  以上條列的能力對非資訊專長出身的國小教師來說,是零散、複雜需逐步整合及長時間進修培養的。尋找坊間的書籍和網路上的ASP教學站台,罕有人把這些學習內容整合成教學文件 ,能夠讓學習者以〝站在高崗上向下望〞的角度去學習ASP程式設計。除了 Html 和 ActiveX 兩項外,本文嘗試盡量以介紹/實作的方式,來循序介紹以上系列課程。

    希望您讀完本課程後,再從眼底看網頁程式寫作這件事情,能像 Matrix(駭客任務)片尾 Neo 眼裡所看到的電腦人和牆壁一樣,變得條理清晰、了然於心。

  雖然 ASP.NET 好像又要開始在 Windows Server 2003 上引領風騷、Linux/windows 上Unix/PC 雙作業系統都能跑的 Apache / PHP / MySQL 也不斷推出整合、功能強大又完善、而且免費的新套件,但是對台北市中小學目前的系管/網管需求而言,ASP還算是滿好用的工具,因為它簡單且能快速上手,非常適合WEB應用程式開發入門。

 

、ASP簡介

  微軟公司的ASP (Active Server Pages) 是一種在伺服器端執行的描述程式稿(Server Side Scripting ) 。ASP 程式碼在 Server 端執行後,Web Server(IIS) 會送出 HTML 標籤與文件給用戶端,用戶端就可以從瀏覽器上看到互動的網頁資料和內容。它不像一般的用戶端描述程式稿(如 Java Script )是在客戶端電腦上的瀏覽器執行,因此 ASP 程式並不會發生因為使用者用了不同的瀏覽器而有因為不完全支援程式設計者所寫的 Script 的情況。也就是說使用 ASP,一般來說不用擔心用戶端的瀏覽器是否版本支援程式創作者的程式稿。

 

ASP的執行環境

    目前支援 ASP 的Web Server MicroSoft WinNT/2000/XP 的IIS 4.0/5.0/5.1 及 Windows 98/SE/ME PWS(Personal Web Server)。

  您可以在自己的 Windows98/ME/NT/2000/XP 電腦上安裝 IIS/PWS 作 ASP 程式寫作練習,然後再用瀏覽器透過 http(內定為Port80)的方式,來連上自己電腦上的 WEB  Server,並可看到自己的 ASP 執行後的結果,開啟的方法有:

開啟本機站台,無需網路連線: http://localhost/   http://127.0.0.1/  http://john/

開啟遠端站台,有網路連線:[虛擬ip]http://192.x.x.1/  [真實ip]http://163.21.224.4/   [區網內]http://john/

開啟遠端站台,有網路連線及dns註冊登記: http://dd.ysps.tp.edu.tw/

 在本機安裝 IIS 的做法,通常是網頁設計者在網頁設計階段使用的,Windwos 2000 Professional 版也和 PWS 一樣小器,有10個連線上限的限制。真的要架設 IIS 網站伺服器,應該在有安裝 Win2000 Server 版的機器上安裝 IIS。

 

ASP的優缺點

ASP的優勢

  1. 使用描述程式稿語言 (Javascript 或 VBScript) 編寫。

  2. 簡單易學,不太需要高深的程式設計基礎。

  3. 用記事本就可拿來編寫,縮短網路程式開發時間。

  4. 完全嵌入 HTML 裡頭,與 HTML、Script 語言結合 。

  5. 不需要經過手動編譯(compile)或透過連結程式(Linker)來聯結函式。

  6. 可以抓來的或是自製的 ActiveX 元件擴充程式功能。

  7. 可存取多種類型資料庫(SQL、mdb、xls、text...)。

  8. 可用多種程式語言(VB、Delphi、VC....)設計自己的 ActiveX Server 元件,不用考慮瀏覽器的相容性問題 。

  9. 程式碼是隱藏的,在用戶端僅可看到由 ASP 輸出的動態 DHTML 文件。

  10. 網路上教學範例站台多,範例程式和學習資源都非常豐富。

ASP的缺憾

  1. 只能使用 Microsoft的NT/2000 Server IIS Web Server,Unix 上執行需另外安裝 mod_perl 和 mod_asp 套件。

  2. Win98/ME/NT/2000/XP WorkStation(Professional) 版的作業系統上,安裝 PWS / IIS 有10個連線的限制。

  3. Windows/IIS 作業系統的漏洞百出,需要管理者經常關心修補(patch),以避免駭客或 Cracker 利用系統漏洞入侵IIS竊取或毀損重要資料。

  4. Windows Server 主機 軟體昂貴,需要另外購買 SQL 存取使用權。

  5. MS-SQL 資料庫 效率高但軟體版權昂貴。

  6. 大量使用者上線時,用 MDB 當後端資料庫站台的效能不是很好。

ASP程式設計/編修工具

  1. 記事本:無行號,免費,最陽春的工具,必須熟悉 HTML 及 VBscript 語法;而且,必須自己找上傳的工具,例如 ftp 程式。

  2. 微軟(MS) script Debugger:有行號,免費,不錯的工具,使用介面友善,認得 HTML 及 VBscript 語法,有專案管理的功能,但是沒有上傳的工具。

  1. 微軟(MS)Frontpage2000/2002:有行號于狀態列顯示,專業的網頁設計工具,使用介面友善,認得 HTML 及 VBscript 語法,有網站管理的功能,提供 Web 發送精靈上傳網頁。但 FrontPage 有時會把 ASP 網頁當作 HTML 而改成亂七八糟,一般都是把使用者介面、表單等先用 FrontPage 設計好,再使用 editpule 等工具編寫 ASP 程式碼。

  1. (Macromedia)Dreamweaver/UltraDev:專業的網頁設計工具,獲得多項所見即所得獎項,使用介面友善,支援 CSS,認得 HTML、Javascript 及 VBscript、ASP 語法,有網站管理的功能,提供 ftp 上傳的介面工具。

        其他編輯軟體,推薦 Editplus2:ShareWare,支援中文、有程式行號、支援正規表示式、巨集取代、函數自動變色、認得HTML、Javascript 及 VBscript、ASP、Perl、PHP、C 等語法,支援 PC/Mac/UNIX 檔案格式,有 html 預覽功能,直接拖曳圖片自動產生 html tag 等等功能,是小而美的軟體。下載 editplus.zip ShareWare版。

 

習題:請把電腦上的Editplus安裝和進階設定完成。


 

ASP與六大物件的運作方式:

  ASP 是一種內嵌在網頁中的 CGI(共通閘道介面)。CGI 是一種由 Web Server 執行的應用程式,執行時間上因為 CGI 要將程式處理的結果丟回給 Web Server,因此有時間上的限制(預設值為 90 秒)。也就是說,我們在設計程式的時後要考量執行效率,不能超過 Time Out,常見的做法是將大型系統分解成許多小支程式來撰寫。

  ASP 與傳統 CGI 應用程式不同之處,在於 CGI 是以獨立程序在獨立記憶體空間執行,ASP 則是以 Web Server 的子程序在 Web Server 規劃的記憶體內執行,前者安全性較高,後者效能較好。由於 CGI 採用的語言比較艱深冷僻,寫作難度較高,而 ASP 是為了大幅簡化開發 Web Computing 所設計的 ,採用 VB Script 這種初階基礎語言,比較友善易於親近。

  我們來看看ASP 是怎樣透過六個內建物件,來完成其 CGI 運作機制的: 

ASP運作概圖(取自IIS Help)

  1. 當Web Server開機跑起來後,首先執行的是 Application物件,它定義了啟動IIS後Web站台運作所需的整體變數,並且會把這些變數一直放在記憶體中,等待ASP程式存取,一直到IIS Shutdown才消失。

  2. 當我們打開瀏覽器並輸入網址,也就是對Web Server送出 Request 要求,Web Server會自動進行 MIME 判別,並採取Windows一貫慣用的方法,也就是從檔案的附加檔名去判斷要交給哪個 DLL 來執行或解譯。

  3. 如果發現要處理的檔案附檔名是 .ASP 類型的檔案,就將此檔案交給 ASP.DLL 這個動態連結函式庫處理,它會將先將 Web Server 所收到的 URI 處理好,並儲存到記憶體裡面, 我們在寫 ASP 程式時可以用 Request 物件將這些資料取出來使用,同時讀取程式碼進行解譯和執行。Request 變數的有效期間較短,只能維持到 ASP 程式執行完畢之前。

  4. 執行ASP程式時如果發生錯誤,就會進行錯誤處理,自動將程序中斷,並且傳送錯誤訊息給Web伺服器傳送給瀏覽器。如果能順利執行完畢,則將結果使用 Response 物件傳送給Web Server,然後再由 Web Server 將網頁傳給使用者的瀏覽器。Response 變數會在 buffer 停留很短的時間,當 buffer 功能未開啟時,則直接送回給參觀者,而不儲存在記憶體內。

  5. ASP 動態函式庫一旦執行,就會常駐在記憶體內,一直到關機為止才結束(稱為 in-process),因此它的執行效能遠高於附加檔名是 exe 或 com 的應用程式(通常這一類應用程式的執行方式就稱為 out-process)。由於使用 in-process 方式處理,所以 ASP 的內建物件 Application 才有辦法運作。也正因為ASP屬於 in-process 的關係,所以如果想要變更 ASP 相關的系統設定,必須將伺服器重新開機才會生效。

  6. Session 物件用來維護每個瀏覽器連線的資訊,當我們要讓ASP程式能夠根據不同身分執行不同功能的時候,就會使用 Session 變數。此變數的有效時間預設是20分鐘,但是有〝連選得連任〞的特性,也就是說當網頁重新整理(Reload)後,Session的有效時間也跟著延長。但最長也只能維持到瀏覽器關閉,或清除 cookie 為止。

  7. 與伺服器有關的相關設定,則是透過 Server 物件來與 Web Server 溝通,例如:呼叫自家的函式庫、修改 Timeout 設定、讀取主目錄的絕對路徑、使用 HTML 或 URL 編碼(Encode) 法來處理 Response 變數等。

  8. ObjectContext 物件則是與 CGI 運作機制不相干的物件,它用來管理 MTS(Microsoft Transaction Server)。MTS 允許在執行程式前先紀錄伺服器狀態,如果有部分程式執行失敗,則可以退回到 先前的狀態,只有當所有相關程式跑完且執行成功後,才會真正登錄改變後的伺服器狀態,就像是我們為 ASP 程式設定了還原點一樣,可以避免程式執行失敗之後,要自行復原伺服器狀態的麻煩。

  9. MTS 通常使用在有需要較高的安全性、和多個程式需要作〝同步〞的場合,一般我們是用不到的。由於 MTS 對於記憶體的需求較高,如果我們網站設計上沒有這個需要,卻故意去使用它,那麼將會白白浪費許多Web Server 的系統資源。

  10. ASP 僅能以 IUSR_WebServer 這個帳號來執行,造成許多伺服器管理的工作必須以 administrator 權限來執行,所以 ASP 無法呼叫 WindowsAPI 來取得系統帳號和應用在伺服器管理工作上,例如:帳號管理、設定檔案目錄權限、修改系統登錄......等等。

  11. ActiveX 物件是將想要達成特定目的的程式封存在一起,形成一個獨立自足的物件。我們只要在ASP程式中對系統提出建立該物件的需要( Server.CreatObject),就可以完成特定工作,不需要再去編寫程式碼。ActiveX 物件讓我們可以像堆積木一樣的方式來設計程式,使得程式設計越來越快,越來越容易。

  12. 微軟公司基於ASP受限較多,因此開發了一些給 ASP 專用的 ActiveX 物件,例如我們常見的 計數器、廣告輪撥器(Ad Rotator)、檔案系統物件(FSO)、資料庫物件(ADO)、SMTP元件...等等。

  13. ASP 所編寫的程式,並無法編譯成 ActiveX 物件,這就讓許多程式設計師,無法將成果作品編譯後打包發行,如果想要分享就必須公開原始程式碼,再不然只能 把程式碼編密;前者會與作者的利益衝突,後者則需保留原始程式碼,每次修改後都還要再進行一次編密,超難維護。

本文編修自李忠憲老師 asp概論一文,原文網址: http://www.spps.tp.edu.tw/documents/memo/asp_web_design.htm

作業:請用自己的方式敘述 IIS與六大物件的運作關係


 

叁、ASP程式設計

經過上面的暖身,您是不是已經手癢想要開始設計ASP程式了呢?

關於程式設計這個議題,先要給各位的建議是:多看、多思考、多寫和不怕錯!

(一)、ASP 基礎練習

  現在假設您已經安裝好了IIS,我們可以用文字編輯器,如 EditPlus,開啟一個 HTML 文件,當作編寫 ASP 程式的視窗,並且把文件存成副檔名為 .asp 存檔到 c:\Inetpub\wwwroot\test.asp;另外再用瀏覽器輸入網址 http://你的電腦名稱/test.asp 來一面寫,一面測試自己寫的ASP程式。

我們先來看看ASP程式碼怎樣放到html文件中使用

 <html>

    <body>

   <% ...這一段是ASP程式碼...... %>

    <body>

</html>

以下幾種使用<% %>符號來把 asp 程式碼放入HTML中的方法,都是合語法規定可被接受的:

左右夾

        例:<% response.write "我來了!" %>

換行夾:
        例:<% response.write "我來了!親愛的asp!"
                %>

三明治夾法:
                <%
                    response.write "我來了!親愛的asp!"
                %>

有時候,我們會在程式碼裡面加註一些說明文字,來幫助我們在編寫程式或偵錯程式時,容易閱讀,寫法像這樣:

    <%  ' 這個是註解的符號,這行asp不會被執行

            '第二行也是一樣

            response.write "Hello World !"

 %>

我們也習慣用鍵盤左邊的定位鍵(Tab鍵)來把程式碼作縮排,以方便閱讀和判斷程式區塊,例如:

<%
    if sex = "boy"  then
        response.write "你是男生"

    else

        response.write "你是女生"

    end if
%>

以上幾種方法我們要常常提醒自己,養成寫作習慣,對未來寫作ASP程式幫助很大。

 

Response 物件裡的 Write 方法

  ASP 中使用 物件.方法 這樣的語法,這跟前面介紹的 JavaScript 是一樣的:

    Response.Write "要印出來的字串"

    response.write "要印出來的字串"

  這樣的語法用來把文字印到瀏覽器上,您一定已經從上面的例子了解了。值得注意的是,ASP 程式碼中使用到的物件,其實是不分大小寫的,這和 JavaScript 會區分大小寫是不同的,但為了容易閱讀,大家還是習慣把字首大寫。

Response.write 除了可以印出字串以外,他也可以用來印出函數或變數的值,例如我想印出現在的日期和時間,可以用:

<%   response.write now( ) %>

  其中 now() 是一個 VB 的內建函式,所謂內建函式,簡單來說,就是古聖先賢已經替您寫好的程式碼片段,而您只要呼叫他來用就好了。利用函 式我們可以節省很多的程式撰寫時間,就像我們要去旅行,開車去加油站加無鉛汽油就好了,不必自己買設備和原油來煉油。

在ASP裡面我們可以把 <% response.write  變數或函式%> 簡化寫成<% = 變數或函式 %> ,下面兩行印出的結果是一樣的︰

<%   response.write now( ) %>

<%   = now( ) %>


(二)、使用變數

ASP 跟大多數的程式語言一樣,指定值給變數的方法是相同的:    變數名稱 = 值

例如:

<% '指定數值 40 給變數 cake
    cake = 40

                '把變數 text 的值印到瀏覽器上
            response.write "奶油蛋糕單價 = "  & text  & "元"

         %>

本段程式碼中的新面孔〝&〞符號的功能是用來連接 Response.write 後面的 "字串"和 "變數"的。回想一下,JavaScript 則是使用〝+〞,不要搞混了!

上面這段程式印出的是:

奶油蛋糕單價 = 40元

(三)、函數裡的函數?

函數可以在括弧中再引用另一個函數,例如:

<% = year(now()) %>

處理的順序是先用括弧裡的 now() 函數取得現在的日期,再把這個值傳回給 year() 函數,year() 函數會篩選出年份部分的資料,最後會印出目前的西元年份

看看下面的程式:

用now( )函數印出日期時間 : <% =now()%>

<hr>

用幾種不同的時間函數分別印出:<br>
今天是中華民國
<% =year(now())-1911 %> 年
<% =month(now()) %> 月
<% =day(now()) %> 日
星期 <% =weekday(now())-1 %>
時間是<% =time() %>

結果是:

(四)、簡單的 For...Next 迴圈

        我們可以把重複性的工作交給迴圈。ASP 延襲 VB 的 For... Next 迴圈語法,例如:

<!-- 以下是簡單的迴圈 -->

    <% '由小到大

     for i = 1 to 7 %>

        第<% =i %>次:<font size="<% =i %>" face="標楷體">印出字形尺寸由小到大[font size=

            <% =i%>

        ]<br>

    <% next %>

<hr>

    <% '由大到小

        for i = 7 to 1 step -1 %>

        第<% =i %>次:<font size="<% =i %>" face="標楷體">印出字形尺寸由大到小[font size=

            <% =i%>

        ]<br>

<% next %>

印出的結果是:


 

For ...Next 迴圈中使用step = -1 來控制變數 i 的值由大到小,網頁程式中我們常常會看到有年、月、日可以挑選的下拉式表單

請挑選:月份的計畫

大部分月份或日期就是用迴圈跑出來的。

請挑選:<select size="1" name="year">
<option><% =year(now())-1911+1 %></option>
<option><% =year(now())-1911 %></option>
<option><% =year(now())-1911-1 %></option>
</select>年

<select size="1" name="month">
    <% for i = 1 to 12

        if i < 10 then

            i="0" & i

        end if

    %>

    <option> <% =i %> </option>
    <% next %>
</select>月份的計畫
 

(五)、If...Then 條件判斷

上題的灰色文字部分就是我們常用的 If.. Then 敘述,通常用在程式的流程控制,除了一般的數值大小判斷外、它也可以判斷真、偽值,或字串內容。要特別記住的是:IF..Then 敘述以 End IF 來結束判斷。可以使用巢狀判斷式。

上例中的:

        if i < 10 then

            i="0" & i

        end if

意思是:當 i 的值小於10的時候前面要自動補"0"

以下是另一個依照現在時間自動判斷要用哪個問候語來問候訪客:

<%

' 把現在時間的[時]的值,指定給 my_Hour 這個變數

    my_Hour = Hour(Now())

    If my_Hour < 12 Then

        '判斷式的前段 [if ....then ]

        Greeting = "現在是" & my_Hour & "點,早起的鳥兒有蟲吃"

        '注意:印出字串要用雙引號來夾住,印出變數則不必.而印出的字串和變數之間要用 &[讀作:and] 符號來連接

    Else

 

        Greeting = "現在是" & my_Hour & "點,午餐吃的飽嗎?"

    End If
'判斷式的結尾

<% = Greeting %>

執行結果:

 

作業:續接上題例,請寫一個包含年、月、日、時的下拉式表單,並且能自動跳到現在的年月日和時間的ASP程式。

(提示:下面的提示幫您做到了年、月請把日、時補上)

請挑選:<select size="1" name="year">
<option> <% =year(now()) - 1911+1 %></option>
<option selected><% =year(now()) - 1911%></option>
<option><% =year(now()) - 1911 -1 %></option>
</select>年<select size="1" name="month">
<% for i = 1 to 12 %>
    <% if i = month(now()) then %>

        <option selected value="<% =i%>"><% =i%></option>
    <% else%>

        <option><% =i%></option>
    <% end if %>
<% next%>
</select>月份的計畫</p>

  ASP 中所使用的變數,不像其他的程式語言,需要事先宣告,也沒有大小寫的問題。

  ASP中的變數在 IIS 上實際執行的生命週期,通常只有一瞬間,當程式執行結束,變數也歸零。雖然如此,我們在替變數命名時,還是要盡量避免變數名稱取得太簡單、太接近,因為容易造成誤解造成日後維護程式的困難。

    變數不能用數字來命名,至少要有一個字母。下面對變數的命名就是一個失敗的例子:

7="7"

5="L2"

21 = 46*3

if = 3-4

day() < "String"

   如果我們養成習慣使用 my_name、start_day、this_table 等方式作為變數名稱,閱讀和維護起來都算清晰容易。

        如果判斷式要判斷的情形太過複雜,我們可以加上〝 Else〞語句,以加廣判斷的範圍,例如:

<%

    my_age=request("age")

     if my_age >= 30 then

        response.write "30而立"

    elseif my_age >= 40

        response.write "40而不惑"

    elseif my_age >= 50

        response.write "50而知天命"

    else

        response.write "年輕人,立志向學!"

    end if

 %>

(六)、Select Case 條件判斷

If.. Then 一樣,用來做分支判斷,但僅適用於判斷同一個值的變化,它會根據 case 的值有所不同, 而執行不同的程式片斷。判斷式的結尾使用 End Select 敘述,例如:

number = int( request("my_number"))

Select  case  number

    case 1

        response.write "number = 1"

    case 2

        response.write "number = 2"

    case 3

        response.write "number = 3"

end Select

 

(七)、While...Wend 迴圈

        這個迴圈最常被用來作逐筆讀取資料錄用的迴圈,當條件成立執行下面的敘述,直到條件不成立。結尾行是〝Wend〞。

        while not rs.eof

            i=i+1

            rs.movenext

        wend

(八)、Do...Loop 迴圈

        Do until 後面跟著條件式,當條件符合的話,執行下面的敘述,直到條件不成立。結尾行是〝loop〞。

    x=100

    do until x < 1
        x = x- 1
        response.write x & "<br>"
    loop

下面的寫法,作用相同:

    x=100

    do
        x = x- 1
        response.write x & "<br>"
    loop while x>1

 

(九)、For Each x  in y  迴圈

        y 必須是一個陣列或物件集合,x 是一個變數。For Each 會逐筆取出 y 陣列裡面的各個元素,再指定給 x 。結尾行是〝next〞。

底下這個範例,將會逐一讀取上個網頁所送出的表單資料(Request.Form),並將所有的值輸出在網頁上:

  for each data in Request.Form

      response.write "表單元件" & data & "的值是" & Request(data) & "<br>"

  next

 

(十)、Response.redirect 網頁轉向

    Response 物件的另外一種常見的用法是 Redirect,它可以讓程式執行到這裡時,對 Server 重新送出新網址的要求,看起來就是從這個網頁轉向到另外一個網頁,寫法為 Response.Redirect。

    我們也可以使用 Server.Trasfer 物件來轉向網頁,不同的是 Server.Trasfer 的處理是由 Server 端直接掌管轉向的工作,Response.redirect 則是由 Client 端發送網頁轉向的要求。

    下一個例子我們要先準備好星期日到星期六的網頁,共計七個檔案。檔名類推是〝星期~.htm〞,網頁內容各編寫成不同的訊息。例如:

html檔名

html裡的內容

星期0.htm <html><body>今天星期日,猴子過生日</body></html>
星期1.htm <html><body>今天星期一,猴子穿新衣</body></html>
星期2.htm <html><body>今天星期二,猴子肚子餓</body></html>
星期3.htm <html><body>今天星期三,猴子去爬山</body></html>
星期4.htm <html><body>今天星期四,猴子要考試</body></html>
星期5.htm <html><body>今天星期五,猴子去跳舞</body></html>
星期6.htm <html><body>今天星期六,猴子去斗六</body></html>

    想法:我們可以使用 weekday() 函數取得今天是星期幾,然後再把網頁轉到這個函數傳回的數值專屬的網頁檔案。

    但是實際上 weekday( ) 函數取得的數值,和我們想法有一點出入:

weekday(now())取得的值

要轉向的檔名

weekday(星期日) = 1

星期0.htm

weekday(星期一) = 2 星期1.htm
weekday(星期二) = 3 星期2.htm
weekday(星期三) = 4 星期3.htm
weekday(星期四) = 5 星期4.htm
weekday(星期五) = 6 星期5.htm
weekday星期六) = 7 星期6.htm

所以我們在 weekday(now()) 函數取出星期的值之後,要記得減去 1:

 <% my_week=weekday(now()-1)%>

<% response.redirect "星期" & my_week & ".htm" %>

今天是星期六,執行後出現的結果是:

上例這種網頁轉向的功能可以用來讓訪客一周裡面的每一天都看到不同的網頁,我們也可以用校內外電腦的IP來做自動判斷,如此,就可以讓校內師生和校外訪客看到的網頁內容不一樣了。

(十一)、Application 物件的應用

Application變數始於IIS啟動,一直要到關機才消失。算是壽命最長的變數了,我們可以利用Application 的這個特性來做網頁訪客計數器:

<%
        ' 先鎖住application變數,避免多位瀏覽者同時存取
    application.lock

        '把application變數的值加一後,重新指定給application變數
    application("count")=application("count")+1

        '記得要解除application變數鎖定
    application.unlock

%>

您是本站第 <% =application("count") %> 位參觀者

結果是:

註:

 Application 變數在 IIS 關掉後就會消失,所以要設計可靠的訪客計數器,比較可行的方法是用 FSO 物件寫入文字檔,或將訪客數寫入資料庫中。

   常見的使用 Application 的例子是聊天室和線上人數這兩類的程式。也因為 Application 變數存活期間很長,相對要耗用主機上較多的系統資源,不斷耗用系統資源造成系統資源不足主機當機,只好重新啟動電腦才能將資源釋出,所以一個好的網站管理員 會有節制的使用 Application 物件。

(十二)、網址列傳值

ASP程式可以透過 Request 物件取得從網址列輸入的資料,請看以下範例:

<% my_answer=request("ans") %>

請在網址列輸入→?ans=1~9 或A~Z

<hr>

<% '如果有輸入了
if my_answer<>"" then %>

    您輸入的 ans = <font color="red" size="7"><% =my_answer%>

<% '否則印出尚未輸入的訊息
else %>

    您尚未在網址列輸入資料

<% end if %>

本範例執行的結果:

 

(十三)、表單傳值

<% my_answer=request("ans") %>

form method="POST"  name="ex7"  action="範例7_利用表單傳值.asp">

<p>請輸入您的暱稱 : <input type="text" name="ans" size="20">
<input type="submit" value="提交" name="B1"><input type="reset" value="重新設定" name="B2"></p>

</form><hr>

您輸入的暱稱是 : <font color="red" size="7">

<% =my_answer%>

請輸入您的暱稱 :

 


您輸入的暱稱是 :

(十四)、表單傳值給自己

<% '把表單傳來的值分別指定給三個變數
' request("值")是較省略的寫法.也可以寫為 request.form ("值"),但是這樣就一需要用表單來傳

my_answer=request("ans")

my_email=request("email")

my_option=request("option")

%>

<html><body>.....略...

<form method="POST" name="ex7" action="範例8_表單傳值給自己.asp">

<p>請輸入您的暱稱 : <input type="text" name="ans" size="20"></p>

<p>您的電子郵件:<input type="text" name="email" size="20"></p>

<p>您對本站的意見 : <textarea rows="2" name="option" cols="49"></textarea></p>

<p> </p>

<p align="center">&nbsp; <input type="submit" value="提交" name="B1"><input type="reset" value="重新設定" name="B2"></p>

</form><hr>

<% '判斷三個欄位都填寫了,而且也有傳來值

if my_answer<>"" and  my_email<>""  and  my_option<>"" then

%>

謝謝您!!

<hr>

您輸入的暱稱是 : <font color="red" size="7"><% =my_answer %> <br>

您輸入的EMAIL是 : <font color="green" size="7"><% =my_email %> <br>

您輸入的意見是 : <font color="blue" size="7"><% =my_option %>

<%'別忘了判斷式結尾

else

response.write "您有欄位沒填寫"

end if%>

</body></html>

執行結果:

 

請輸入您的暱稱 :

您的電子郵件:

您對本站的意見 :

 

 

 


您有欄位沒填寫

(十五)、表單傳值給另一支 ASP 程式

<table border="1" width="100%">

<tr>

<td width="50%">

<form method="POST" name="ex7" action="範例9_的結果.asp">

<h1 align="center"><font color="#FF0000">訪客留言</h1>

<p>請輸入您的暱稱 : <input type="text" name="ans" size="20"></p>

<p>輸入您的電子郵件:<input type="text" name="email" size="20"></p>

<p>寫下您對本站的意見 : <textarea rows="4" name="option" cols="49"></textarea></p>

<hr>

<p align="center">&nbsp; <input type="submit" value="送出我填寫的表單內容" name="B1"><input type="reset" value="擦掉重寫" name="B2"></p>

</form>

<p></td>

<td width="50%"> </td></tr>

</table>

執行後看起來像這樣:

訪客留言

請輸入您的暱稱 :

輸入您的電子郵件:

寫下您對本站的意見 :


 

 

 

(十六)、接受傳值的 ASP 程式表單資料印出

<% '把表單傳來的值分別指定給三個變數

my_answer=request("ans")

my_email=request("email")

my_option=request("option")

%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=big5">

<title>範例9的結果</title>

</head>

<body>

<table border="1" width="100%">

<tr>

<td width="50%">

<hr>

<% '判斷有沒有傳來值

if my_answer<>"" and my_email<>"" and my_option<>"" then

%>

謝謝您!!前面的表單已經把值傳來,列出如下

<hr>

您輸入的暱稱是 : <font color="red" size="7"><% =my_answer %> <br>

您輸入的EMAIL是 : <font color="green" size="7"><% =my_email %> <br>

您輸入的意見是 : <font color="blue" size="7"><% =my_option %>

<% else%>

<font size="7" color="red">您尚未填寫完成留言版,

<hr>

請按<a href="範例9_把表單傳值給另一個asp程式處理.asp">這裡回表單頁填寫</a>喔

<%

'別忘了判斷式結尾

end if

%>

(十七)、Session 物件的應用

    Session 的功能其實相當於 Cookies ,是用來紀錄瀏覽器與 Server 端的連線資訊用的。當使用者把所有開啟的瀏覽器視窗關閉時,這個工作階段的 Session 就消失了。

    如果瀏覽器一直沒關,Session 也有預設存活期限20分鐘的限制。

    雖說我們可以手動來調整 IIS 中 Session 的TimeOut 設定,但是 Session 的  TimeOut 預設值算是合理,除非您清楚的知道你在幹什麼,或有特殊應用的場合,這裡不建議自行手動修改。下表是我們學習ASP程式設計必須要知道的幾種TimeOut 的預設值。

ADSI

預設值 (秒)

可否在 IIS 嵌入式管理
單元中設定?

AspScriptTimeout

90

AspSessionTimeout

1200 (20 分鐘)

ConnectionTimeout

900 (15 分鐘)

CGITimeout

300 (5 分鐘)

AspQueueTimeout

-1 (無逾時)

    我們常會用 Session 的這種短時間記憶的特性, 在網頁設計時,拿來做一些像是使用者帳號、職稱、權限等資訊,在不同網頁之間傳遞的媒介。

    我們先用FrontPage 製作一個表單,再加入ASP程式碼:

您還沒有填寫資料喔

請輸入您的暱稱 :

您的電子郵件:

測試session計數器

此頁被您看了 : 1次[關閉所有瀏覽器就會消失]

您對本站的意見 :

 

 

  程式碼如下

  <% '把表單傳來的值分別指定給三個變數

  my_answer=request("ans")
  my_email=request("email")
  my_option=request("option")

  if my_answer = "" or my_email="" or my_option= "" then

    response.write "<font color=red size=5>您還沒有填寫資料喔"

  else

  '如果有填寫,把值指定給三個session

    session("ans")=my_answer
    session("email")=my_email
    session("option")=my_option

  %>

您輸入的暱稱是 : <font color="red"><% =session("ans") %> <br>

您輸入的EMAIL是 : <font color="green"><% =session("email") %> <br>

<p><font color="#FF0000">

測試 Session 計數器 :此頁被您看了

<% session("count")=session("count")+1
response.write session("count")%>次[關閉所有瀏覽器就會消失]</p>

您輸入的意見是 : <font color="blue">

<% =session("option") %> <br>

請您點一下重新整理按鈕,或者連到首頁再回來看看,以上資訊並不會清除,session 依然存在</p>

<p><font color="#0000FF">session物件替每個上網的瀏覽器保留變數值,瀏覽器關閉就結束,不像Application,要等到IIS [Web伺服器]關畢才會結束。</p>

<p>相關範例 :

<a href="範例5_application網頁計數器.asp">範例5_application網頁計數器.asp</a></p>

<hr>

<% end if %>

 

(十八)、怎樣丟棄所有 SESSION

在網頁上要求使用者做重新登入動作時,我們也同時想要清除這個使用者的連線資訊可以用 Session.abandon 這樣的方法來清除。

<%
session.abandon
%>

您輸入的暱稱是 : <font color="red"><% =session("ans") %> <br>

您輸入的EMAIL是 : <font color="green"><% =session("email") %> <br>

您輸入的意見是 : <font color="blue"><% =session("option") %> <br>

執行結果:

您輸入的暱稱是 :
您輸入的EMAIL是 :
您輸入的意見是 :

(十九)、怎樣查看現有 Application Session 的數值?

        為了能清楚了解,我們可以用For ... Next 迴圈印出這台 Server 目前存在的 Application 的值,和這台電腦和 Server 間的 Session 的值。

<%

on error resume next

  for each item in Application.contents
       response.write item & "=" & application(item) & "<br>"
  next

  for each session_item in session.contents
        response.write session_item & "=" & session(session_item) & "<br>"
  next

%>

輸出結果是:

小小留言版_ConnectionString=DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\inetpub\wwwroot\fpdb\gbook.mdb
小小留言版_ConnectionTimeout=15
小小留言版_CommandTimeout=30
小小留言版_CursorLocation=3
小小留言版_RuntimeUserName=
小小留言版_RuntimePassword=
spps=DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\inetpub\wwwroot\fpdb\training.mdb
ysps_ConnectionTimeout=15
ysps_CommandTimeout=30
TotalUsers=2
210.85.156.6LastAccess=
61.59.71.81LastAccess=
61_59_71_81show=
...............略........

作業:以 access 建立 mdb 格式資料庫,製作含分頁功能的留言版 

下面這個範例可以不用撰寫asp程式碼,而直接以 access 建立 mdb 格式留言版資料庫。範例:我的小小留言版

以 Access 開一個新的資料庫,並替檔案命名,如gbook.mdb ,並暫時先存在桌面上

使用資料庫設計精靈建立一個簡單的資料庫,您熟的話可直接用設計檢視一步步完成以下各欄位的設計

資料庫中包含

姓名→文字,長度20

電子郵件→文字,長度50

留言內容→文字,長度255

留言時間→日期,

等 四個欄位

下面幾個步驟是利用〝精靈〞來建立資料庫,若您直接使用設計檢視,則可以跳過以下三個步驟:

1.選個人→再把需要的欄位放入最右欄,不滿意精靈取的欄位名稱,自己改

2.替這個資料表取個名字,例如:留言版 。精靈也會問你要不要作索引?

3.按完成按鈕,完成資料庫的設計

完成設計資料表後,隨便輸入一筆資料,您可看見id值自動產生

以FrontPage →檔案→開啟web→ 輸入 http://你的網頁/網址/ 

紅燈熄滅表示你的web網站已載入完成。

把FrontPage切換到 檢視→資料夾 模式 。

用滑鼠拖曳桌面上的 gbook.mdb 資料庫,到您開啟的 web 中

FrontPage會詢問要用什麼名稱來取名:例如小小留言版

這時候系統自動問要不要把這mdb檔放到網頁根目錄的 /fpdb 中,點確定

這時你網頁的 /global.asa 檔會自動更新資料庫的連結字串

匯入後的mdb檔,內定放在 網頁根目錄的 ftdb 資料夾中,桌面上的那份就可以刪除了

以FrontPage 切換到網頁模式,開一個空白網頁,並點 插入→表單

設計一個表單,包含 姓名[單行文字方塊]、電子郵件[單行文字方塊]、留言內容[多行文字方塊]

依以上範例打造,完成表單。

在表單上按右鍵,選表單內容

指定→傳送到資料庫→按左下角的選項

設定資料庫

按下確定→找不到指定欄位→逐一手動指定

T1→姓名

T2→電子郵件

S1→留言內容

設定完畢後,Frontpage會提醒您 副檔名要改為  .ASP

在網址列輸入 http://你的網址/帳號/留言版路徑/我要留言.asp

填寫一份留言內容,按 提交 [送出表單內容]

出現表單收到內容的確認畫面

資料雖已入庫,但是在網頁上還要新增一頁,用來秀出現在已經留下留言的內容

不想新增一頁,也可以放在留言表單的下面

在留言表單網頁的最下面點一下,選

插入→資料庫→結果

系統自動找到您曾經匯入的資料庫,選小小留言版

網頁下方自動加上讀取資料庫的表格

在切換到瀏覽器看網頁有什麼不一樣??

我的小小ASP留言版做好了!!

一行asp程式都不用寫喔!

 

範例 : 我的小小留言版

(二十)、回家習題

    請以記事本或FrontPage設計一個表單會自動印出以下最多到9X9乘法表的ASP程式。程式必須判斷使用者輸入的數字必需在1~9的範圍中,並且只能輸入整數

我要印出的乘法表格

 

這是9X9範圍的乘法表

1 x 1 = 1

1 x 2 = 2

1 x 3 = 3

1 x 4 = 4

1 x 5 = 5

1 x 6 = 6

1 x 7 = 7

1 x 8 = 8

1 x 9 = 9

2 x 1 = 2

2 x 2 = 4

2 x 3 = 6

2 x 4 = 8

2 x 5 = 10

2 x 6 = 12

2 x 7 = 14

2 x 8 = 16

2 x 9 = 18

3 x 1 = 3

3 x 2 = 6

3 x 3 = 9

3 x 4 = 12

3 x 5 = 15

3 x 6 = 18

3 x 7 = 21

3 x 8 = 24

3 x 9 = 27

4 x 1 = 4

4 x 2 = 8

4 x 3 = 12

4 x 4 = 16

4 x 5 = 20

4 x 6 = 24

4 x 7 = 28

4 x 8 = 32

4 x 9 = 36

5 x 1 = 5

5 x 2 = 10

5 x 3 = 15

5 x 4 = 20

5 x 5 = 25

5 x 6 = 30

5 x 7 = 35

5 x 8 = 40

5 x 9 = 45

6 x 1 = 6

6 x 2 = 12

6 x 3 = 18

6 x 4 = 24

6 x 5 = 30

6 x 6 = 36

6 x 7 = 42

6 x 8 = 48

6 x 9 = 54

7 x 1 = 7

7 x 2 = 14

7 x 3 = 21

7 x 4 = 28

7 x 5 = 35

7 x 6 = 42

7 x 7 = 49

7 x 8 = 56

7 x 9 = 63

8 x 1 = 8

8 x 2 = 16

8 x 3 = 24

8 x 4 = 32

8 x 5 = 40

8 x 6 = 48

8 x 7 = 56

8 x 8 = 64

8 x 9 = 72

9 x 1 = 9

9 x 2 = 18

9 x 3 = 27

9 x 4 = 36

9 x 5 = 45

9 x 6 = 54

9 x 7 = 63

9 x 8 = 72

9 x 9 = 81

 

  看結果     看原始碼 

        原始碼如下:

<%
var_1=request("var_1")
var_2=request("var_2")
var_1=int(var_1)
var_2=int(var_2)

if var_1 >9 or var_2 >9 then
    response.write "<h2>您輸入的數字超過9了,請重新輸入介於 1 到 9 之間的整數</h2>"
    inputok=0
elseif var_1 < 1 or var_2 < 1 then
    response.write "<h2>您輸入的數字小於1,請重新輸入介於 1 到 9 之間的整數</h2>"
inputok=0
else inputok=1
end if
%>

<html><head><meta http-equiv="Content-Type" content="text/html; charset=big5">
<title>印出乘法表格</title></head>
<body>
<form method="POST" action="9x9.asp">
<p align="center"><b><font color="#FF0000">我要印出
<input type="text" name="var_1" size="4" value="<% =var_1%>"> X
<input type="text" name="var_2" size="4" value="<% =var_2%>"> 的乘法表格</b></p>
<p align="center"><font size="3"><input type="submit" value="幫我印出" name="B1">
<font size="3"><input type="reset" value="擦掉" name="B2"></p>
</form>
<center>
<hr>
<% if inputok=1 then %>
<h2>這是 <font color="#FF0000"><b><% =var_1%> </b>X <font color="#FF0000">
<b><% =var_2%> </b>範圍的乘法表</h2>
</center>
<div align="center">
<center>
<table width="90%" border="1" style="border-collapse: collapse" bordercolor="#111111" cellpadding="3" cellspacing="0" bordercolorlight="#808080" bordercolordark="#C0C0C0">
<% for i =1 to var_1 %>
    <tr>

      
 <% for j=1 to var_2
        answer=i*j    %>
        <td nowrap width="71" align="center"><font color="#000080" size="3"><% =i%>
x <% =j%> = <% =answer %></td>
        <% next %>

    </tr>
<% next%>
</table>
</center>
</div>
<% else %>
    <h1>輸入錯誤</h1>
<% end if%>
</body></html>

 

(二十一)、使用 CDONTS 元件:

        越來越多的 WEB 應用程式要利用到電子郵件寄發,例如:電子賀卡、電子報、申請會員、網頁郵寄...等。這時候就需要使用CDONTS 元件。在 Server 上是由 CDONTS.dll 這個函式庫來負責處理。

我們如果想在網站上使用寄發電子郵件服務的功能,必須先把 IIS 中的 SMTP 伺服器給設定好:

步驟一、設定IIS中的SMTP

 

(二十二)、用 CDONTS 元件試做 Web 網頁寄信程式

步驟二、用 frontpage 等網頁製作軟體,設計一個郵寄程式用的表單:

請點選 檔案→開啟WEB→C:\inetpub\wwwroot
            (也許您將網頁資料夾裝在其他地方,請自行變更)

 

步驟三、建立訪客填寫的介面:

請新增一個表單,並替這個表單命名,名稱取為〝 sendmail〞 好了, 然後指定表單上每個方塊的名稱(name),習慣上我們會用 無框線的表格來對齊這些網頁上的項目,如下圖:

步驟四、設定表單資料要送到哪支 ASP 程式處理?

    我們也要指定這個表單送交給另外一支ASP程式的處理動作,在表單範圍內按滑鼠右鍵,選〝表單內容〞:

點一下:〝選項〞,輸入動作傳給 sendmail.asp ,方法是POST。

 

 設定完畢請〝存檔〞到C:\Inetpub\wwwroot\mailto.asp。

步驟五、製作送出郵件的ASP程式。

    開另一個新檔案,切換到html檢視,撰寫ASP程式碼如下:並存檔為 sendmail.asp

步驟六、開啟瀏覽器測試功能:

步驟七、開啟OE看看收到了沒有?

 

(二十三)、如何印出 Server 的環境變數

    我們想要對 IIS Server 所提供的環境變數更了解的話,最簡單的方法就是把他全部印出來。我們可以寫幾行小程式並使用 Request.ServerVariables 的方法取出 Server 的環境變數。

    但因為內容有敏感性資料,通常這類程式沒事不會故意放在網路上給參觀者看。程式碼如下:

<html>
<% ' 下面的程式碼是用 for each xxx  in ...迴圈讀出環境變數,並放在 vars 變數中,再分別印在兩欄的表格中。

For  Each  vars  In  Request.ServerVariables %>

<table>

<tr><td > <%= vars %> </td> <td > <%= Request.ServerVariables(vars) %> </td></tr>

<% Next %>

</table></html>

程式很簡單,印出來的資料卻很多,執行後的結果如下:

Server 環境變數

ALL_HTTP  

HTTP_ACCEPT:*/* HTTP_ACCEPT_LANGUAGE:zh-tw HTTP_CONNECTION:Keep-Alive HTTP_HOST:dd.ysps.tp.edu.tw HTTP_REFERER:http://dd.ysps.tp.edu.tw/html/2.asp HTTP_USER_AGENT:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Q312461) HTTP_COOKIE:iscookies=0; ip=140%2E131%2E204%2E4; ASPSESSIONIDASTRDSCC=PCFDHPGBPDGCAEDPEILNPNKM HTTP_ACCEPT_ENCODING:gzip, deflate  

ALL_RAW  

Accept: */* Accept-Language: zh-tw Connection: Keep-Alive Host: dd.ysps.tp.edu.tw Referer: http://dd.ysps.tp.edu.tw/html//6.asp User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Q312461) Cookie: iscookies=0; ip=140%2E131%2E204%2E4; ASPSESSIONIDASTRDSCC=PCFDHPGBPDGCAEDPEILNPNKM Accept-Encoding: gzip, deflate  

APPL_MD_PATH  

/LM/W3SVC/1/ROOT  

APPL_PHYSICAL_PATH  

d:\inetpub\wwwroot\  

。。。。。中略。。。。。

GATEWAY_INTERFACE  

CGI/1.1  

INSTANCE_META_PATH  

/LM/W3SVC/1  

LOCAL_ADDR  

140.131.204.4  

LOGON_USER  

PATH_INFO  

/ASP範例/server_variable.asp  

PATH_TRANSLATED  

d:\inetpub\wwwroot\ASP範例\server_variable.asp  

QUERY_STRING  

REMOTE_ADDR  

140.131.204.4  

REMOTE_HOST  

140.131.204.4  

REMOTE_USER  

REQUEST_METHOD  

GET  

SCRIPT_NAME  

/ASP範例/server_variable.asp  

SERVER_NAME  

dd.ysps.tp.edu.tw  

SERVER_PORT  

80  

SERVER_PORT_SECURE  

0  

SERVER_PROTOCOL  

HTTP/1.1  

SERVER_SOFTWARE  

Microsoft-IIS/5.0  

URL  

/ASP範例/server_variable.asp  

HTTP_ACCEPT  

*/*  

HTTP_ACCEPT_LANGUAGE  

zh-tw  

HTTP_CONNECTION  

Keep-Alive  

HTTP_HOST  

dd.ysps.tp.edu.tw  

HTTP_REFERER  

http://dd.ysps.tp.edu.tw/html/2.asp  

HTTP_USER_AGENT  

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Q312461)  

HTTP_COOKIE  

iscookies=0; ip=140%2E131%2E204%2E4; ASPSESSIONIDASTRDSCC=PCFDHPGBPDGCAEDPEILNPNKM  

HTTP_ACCEPT_ENCODING  

gzip, deflate  


(二十四)、如何判斷訪客是來自校內還是校外

 從上面的範例我們可以看到有一項環境變數叫做 Remote_Addr ,我們可以在程式中取出,然後放入陣列中來做判斷,這樣一來就可以知道是校內的訪客或是校外。當然不放入陣列直接用 left(Request.Servervariables("Remote_Addr") ,12)做字串比對來判斷也是可以的:

<%
user_ip=Request.Servervariables("Remote_Addr")

' 把從http檔頭取來的環境變數ip值以點分隔,放入Theip陣列,這樣一來theip這個陣列變數就會放入多筆資料。

Theip = Split(Request.Servervariables("Remote_Addr"), ".")

' 先用Split()函數,來把取回的 ip用 . 分隔,分別放入陣列中,如果是C級網域的話,我們可以取Theip 陣列的前三個元素來判斷訪客來自某處。

' 放入 Session的好處是可以在其他網頁中沿用這個 session 值做一些判斷上的變化

If Theip(0) = "163" and Theip(1) = "21" and Theip(2) = "166" Then '石牌國小ip

     session("spps")=1

elseIf Theip(0) = "163" and Theip(1) = "21" and Theip(2) = "224" Then '逸仙國小ip

     session("ysps")=1

elseIf Theip(0) = "163" and Theip(1) = "28" and Theip(2) = "4" Then '教育部proxy

     session("edu")=1

else

     session("others")=0

end if

%>

<html><body>

<% if session("spps")=1 then

response.write "<h1>歡迎來自石牌國小的訪客</h1>您的ip是:" & user_ip

elseif session("ysps")=1 then

response.write "<h1>歡迎來自逸仙國小的訪客</h1>您的ip是:" & user_ip

elseif session("edu")=1 then

response.write "<h1>歡迎來自教育部PROXY</h1>您的ip是:" & user_ip

else

response.write "<h1>歡迎來自" & user_ip & "的朋友蒞臨</h1>"

end if

%>

</body></html>

    有的時候校內網頁可以用一些 \\web\share 等網址來連結校內主機,我們就可以利用這種判斷校內外ip連線的功能,來設計一些只有校內上網看得到的網頁。或是在主選單上判斷校內的 Session 是否存在,如果是校內電腦則顯示出來,校外就不顯示。

(二十五)、使用 FSO 元件

 IIS上使用 [檔案系統物件] ( FSO, File System Object )可以取得Server 上的磁碟,資料夾和檔案內容資訊,也就是說我們在網頁程式設計應用上,可以利用它的特性來做取得WEB Server 上的檔案名稱、大小、建檔日期等等屬性,當然也可以對檔案做讀寫動作,在 Server 端專門用來解析這個物件的動態函式庫是:scrrun.dll。

在ASP程式中啟用這個物件的語法是:

Set my_FSO = CreateObject("Scripting.FileSystemObject")

    FSO物件在IIS4.0以上有超過20幾種方法,以下是FSO物件常用的幾種常見方法:

屬性/方法 說明
Drives屬性 傳回磁碟代號、磁碟類型、共享名稱、磁碟標籤等
CopyFile方法 複製檔案
CopyFolder方法 複製資料夾
CreatFolder方法 建立新資料夾
Deletefile 、DeleteFolder方法 刪除檔案或資料夾
DriveExists方法 判斷磁碟機是否存在
FileExists 、FolderExists方法 判斷檔案或資料夾是否存在
GetDriveName方法 取得磁碟機名稱
GetExtensionName方法 取得檔案的副檔名
GetParentFolderName方法 取得上層資料夾名稱
MoveFile方法 搬移檔案
MoveFolder方法 搬移資料夾

對於文字檔的讀寫,我們可以使用 FSO 物件的子物件: TextStream ,下面是這個物件的屬性和方法

AtEndOfLine屬性 判斷是否是文字行的最後一個字元
AtEndOfStream屬性 判斷是否是文字檔內容的最後(結尾)
OpenTextFile 方法. Close 方法 開啟/關閉文字檔
Read方法 讀取文字內容
ReadAll方法 讀取文字檔案內全部文字內容
ReadLine方法 逐行讀取
Write方法 寫入字串
Writeline方法 寫入一行字串
WriteBlankLines方法 寫入一行空字串

我們來做個FSO的語法的練習:

<%
    mydir = request("dir")                                    '取得路徑字串放入變數
    realpath = server.mappath(mydir)                      '取得絕對路徑
    set my_FSO=CreateObject("Scripting.FileSystemObject")             '使用FSO物件

    set my_folder=my_FSO.getfolder(realpath)    '取得資料夾路徑
    set folder_content=my_folder.subfolders        '取得這個資料夾內的所有子資料夾
    set file_list=my_folder.files                        '取得這個資料夾的檔案清單

     if my_FSO.FileExists(realpath & "/index.htm") then           '如果這個檔案存在
        response.redirect "index.htm"
    else
        response.write "資料夾中沒有首頁 index.htm 檔"

        response.write file_list
        response.write folder_content
        response.write my_folder
     end if
end if
%>

    上面這個程式片段是檔案管理員的前面部分程式碼,搭配此程式需要有一個指定為message.htm 的純文字設定檔,內容指定網頁標題,圖片的長寬,說明訊息等資訊。

    概括的流程大概是:先利用FSO物件讀取用 Request 物件讀入的路徑,並判斷此路徑是檔案或是資料夾,同時取得了資料夾中的子資料夾名稱和檔案名稱.它也判斷資料夾下面有沒有 message.htm 這個檔案,如果有的話逐行讀取檔案內容,沒有的話,就用把TITLE設為預設值。

    下面這個範例程式稍微複雜一些,它是利用 FSO 物件取得 /top/midi/下面的特定類型檔案(背景音樂檔),並用亂數隨機選取一首音樂在網頁上撥放,但是也尊重使用者,所以也把音樂關閉的功能考慮進去了。以下是逸仙國小上面那個網頁(top.asp)的部分內容:

<%
' 讀取 Request 物件中的 play 變數,以便判斷要不要放音樂
play = request("play")
' 讀取環境變數,並檢查是否為校內 IP

' my_Ip = Left(Request.Servervariables("Remote_Addr"),9)

' if my_IP="192.56.1."  then ...... 判斷前9個字串也可以

TheIp = Split(Request.Servervariables("Remote_Addr"), ".")

If Theip(0) = "140" and Theip(1) = "131" and Theip(2) = "204" Then
    session("inside")=1
else
    session("inside")=0
end if
%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=big5">
<base target="right">
</head>
<body bgcolor="#cceeff" leftmargin="0" topmargin="2" marginwidth="0" marginheight="0">
<%
if play="yes" then
        Randomize                                         '使用亂數
        realpath=server.mappath("/top/midi")        '取得實體路徑
        newpath=realpath
        set f=CreateObject("scripting.filesystemobject")         '使用FSO物件
        set fo=f.getfolder(newpath)         '把路徑指定給 fo 變數
        set fl=fo.files                            '將此路徑下的檔案放入fl 陣列變數中
        redim music(500)                        '開一個可以放入500個元素大小的陣列
        i=0                                           '歸零 
            for each f1 in fl                      '用迴圈取出檔按陣列裡的元素
                if session("inside")=1 then  '檢查是來自校內或校外
                    if Ucase(f1.GetExtensionName(newpath & f1.name))="MP3" then music(i) = f1.name
                                                        '校內:判斷副檔名是不是 MP3,若是則放入music陣列中
                else

                    if Ucase(f1.GetExtensionName(newpath & f1.name))"MID" then music(i) = f1.name

                                                        '校外:判斷副檔名是不是 MID,若是則放入music陣列中
                end if
                i = i + 1                         '計算總共有多少個符合的檔案
            next
        no = Fix(Rnd * i)             '歌曲的總數乘上亂數後的值Fix()處理後,指定給no變數
        response.write "<bgsound src='/top/midi/" & music(no) & "' loop=-1>"
end if
%>

<table border="0" width="100%" cellspacing="0" cellspadding="0">
<tr width="80%">
<td width="641" valign="top" align="left">
<p align="left"><font color="#88aaF2">■<font color="#0080ff"><a href="http://www.ysps.tp.edu.tw/board/index.asp" target="right">最新消息</a> 
<font color="#88aaF2">■<a href="http://webmail.ysps.tp.edu.tw/email/neomail.htm" target="right">網路郵局</a> 
<font color="#66aaf2">■<a href="http://webmail.ysps.tp.edu.tw:12000/" target="teacher">教職員主機</a> 
<font color="#aa4444">■<a href="http://stu.ysps.tp.edu.tw:12000/" target="student">學生主機</a> 
<% if session("inside")=1 then %><font color="#88aaF2">■<a target="right" href="/vod/">隨選視訊</a>  <% end if%>
<font color="#88aaF2">■<a target="right" href="http://webmail.ysps.tp.edu.tw/email/email1.htm">班級網頁</a> 
<font color="#88aaF2">■<a target="right" href="ccfaq.htm" target=right>FAQ[常見問題]</a>
<!-- td align="right" width="1"><a href="http://www.ysps.tp.edu.tw/index1.htm" border="0" target="restore"><img src="restore.gif" border="0" align="right" alt="按這裡開啟一般視窗"></a></td -->
<table border=0 width=100%>
</table>

<td align="left" width="1">

<% if request("play")="no" then %>
<a href="top.asp?play=yes" target="_self" border="0"><img src="no_speak.gif" border="0" align="left" alt="點這裡可以自動點播音樂"></a>
<% end if %>

<% if request("play")="yes" then %>
<a href="top.asp?play=no" target="_self" border="0"><img src="speak.gif" border="0" align="left" alt="現在撥放的音樂曲名是:<% = music(no) %>,按這裡可以關閉音樂!"></a>
<% end if %>
</td>
<td align="left" width="1"><a href="javascript:onclick=window.parent.close()" border="0"><img src="x.gif" border="0" align="left" alt="按這裡可以關閉視窗"></a></td>
</table>

<!-- =============校內ip上網計數,寫入資料庫============= -->
<!-- #include virtual="/use/link.asp" -->
</body>
 

       

圖庫管理員

FSO 這個檔案系統物件在ASP程式的另一種應用,就是膾炙人口的檔案管理員。這個檔案管理員ASP程式請到石牌國小網站→資訊中心→網頁資源庫中下載,本程式由李忠憲老師設計撰寫陸續推出了好幾個版本。應用上非常 廣泛,詳細使用方法請參閱說明檔。我們來看看程式碼:

<%
mydir = request("dir") ' 讀取要瀏覽的目錄,放入字串變數中
mydir = replace(mydir,".","") ' . 移除,以避免用相對路徑(../../winnt/system32)連到未開放存取的上層目錄
if mydir = "" then mydir = "." ' 經過以上處理,如果路徑變成空的,就設為程式所在的資料夾
if left(mydir,1)="/" or left(mydir,1)="\" then mydir = "." & mydir ' 移除 / \ 以防止使用絕對路徑連到不相干的目錄
i = InStrRev(mydir,"/") - 1 ' 搜尋路徑字串中最右邊的 /
if i <= 0 then
    uplevel = "." ' 找不到 /,表示此路徑沒有上層目錄,因此將上層目錄設為程式所在的資料夾
else
    uplevel = left(mydir,i) ' 找到 /,取得 / 左邊的字串,設定為上層目錄
end if
 

realpath = server.mappath(mydir) ' 對應 web 路徑為真實的磁碟路徑
set f=CreateObject("scripting.filesystemobject") ' 建立一個 FSO 物件
set fo=f.getfolder(realpath) ' 將目錄資訊讀取到 fo 變數中
set fc=fo.subfolders ' 將該目錄的子資料夾資訊讀取到 fc 變數中
set fl=fo.files ' 將該目錄的檔案資訊讀取到 fl 變數中

flag=0 ' 設定 message.htm 訊息檔旗號,0 表示沒找到訊息檔
if f.FileExists(realpath & "/message.htm") then ' 在目前的目錄中尋找 message.htm
    set mf = f.OpenTextFile(realpath & "/message.htm") ' 找到的話,將該檔案打開
    flag=1 ' 重設旗號為 1 ,表示已找到
else
    tempdir=mydir ' 為了搜尋上層目錄方便,先將路徑字串放到另一個變數裡,以避免改到原來的路徑
    x=len(tempdir) ' 計算路徑的長度
    do until x<=0   ' 以迴圈來搜尋,當路徑長度逐漸縮短到變成 0,就表示搜尋已到終點,跳出迴圈
        x = InStrRev(tempdir,"/") - 1 ' 找出最右邊的 /
        if x>0 then ' 如果有找到,表示路徑字串中還有上層目錄
            tempdir = left(tempdir,x)  ' 將目前的路徑改到上層目錄
            realdir = server.mappath(tempdir) ' 對應 web 路徑為真實的磁碟路徑
            if f.FileExists(realdir & "/message.htm") then ' 檢查是否有 message.htm
                set mf = f.OpenTextFile(realdir & "/message.htm") ' 找到的話,將該檔案打開
                flag=1 ' 重設旗號為 1 ,表示已找到
                x=0 ' 故意將路徑長度設為 0,以便提早結束迴圈
            end if
        end if
    loop ' 透過迴圈逐一搜尋上層目錄是否含有 message.htm,直到找到或搜尋完畢為止
end if
if flag=1 then ' 找到 message.htm 的後續處理
    do until mf.AtEndOfStream ' 檢查是否已經到達 message.htm 的檔案結尾,若是則跳出迴圈
        oneline = mf.ReadLine    ' 每次讀取一行
        myvar=split(oneline,"=") ' 將該行從 = 號的地方切成兩半
        if myvar(0)="title" then  ' 檢查左半字串是否為 title
            mytitle = myvar(1)     ' 若是,則將右半字串指定給 mytitle 變數,作為變數值
        elseif myvar(0)="width" then ' 檢查左半字串是否為 width
            mywidth = myvar(1)         ' 若是,則將右半字串指定給 mywidth 變數,作為變數值
        elseif myvar(0)="height" then ' 檢查左半字串是否為 height
            myheight = myvar(1)        ' 若是,則將右半字串指定給 myheight 變數,作為變數值
        elseif myvar(0)="number" then ' 檢查左半字串是否為 number
            mynumber = myvar(1)        ' 若是,則將右半字串指定給 mynumber 變數,作為變數值
        else
            messages = messages & oneline ' 如果不符合所有條件,表示該行是要顯示在網頁的訊息,就加到 messages 變數
        end if
    loop ' 透過這個迴圈將會對 message.htm 作逐行剖析,找到相關的組態設定
    mf.Close ' 關閉被開啟的 message.htm 檔案
end if
 

if len(mytitle)=0 then mytitle="【我的檔案】" ' 如果站長沒有指定標題,那就用這個代替
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5">
<title><% =mytitle %></title> <!-- 設定網頁標題 -->
<style fprolloverstyle>A:hover {color: #FF0000}</style>
<script>
function bgcolor(mycolor) <!-- 這支程式用來動態改變顏色,必須代入變數,告訴程式要改成哪個顏色 -->
{
if (mycolor=="") mycolor = "#" + document.all["Red"].value + document.all["Green"].value + document.all["Blue"].value;document.bgColor=mycolor;document.body.background='manager/none.gif';
}
 

function bgpic(picname) <!-- 這支程式用來動態改變背景圖,必須代入變數,告訴程式要改成哪個圖檔 -->
{
document.body.background=picname;
}
</script>
<Script Language="VBScript">
<!-- 

/* 因為程式並沒有真正製作縮圖,網路擁塞時會不知道是否傳完,下面這段 Scriopt 僅供參考用,可以略過 */
Dim Bar, Line, SP
Bar = 0
Line = "■"
SP = 100
Function Window_onLoad()
Bar = 95
SP = 10
End Function
Function Count()
If Bar < 100 Then
Bar = Bar + 1
Window.Status = "載入狀態:" & Bar & "%" & " " & String(Bar, Line)
setTimeout "Count()", SP
Else
Window.Status = "載入狀態:完成"
Document.Body.Style.Display = ""
End If
End Function
Call Count()
-->
</Script>

</head>
<body bgcolor=#ddeeff style="font-size: 9pt">
<h1 align="center"><font color="#008000"><% =mytitle %></h1> <!-- 顯示標題 -->
<% = messages %> <!-- 顯示 message.htm 中的附加訊息 -->
<p align="center" style="margin-top: 10; margin-bottom: 0">目前所在位置:<%=mydir%>
<div align="center">
<hr width=90% color=#FF0000><table border=0><tr>
<%
i=0 ' 將檔案計數器歸零
for each f1 in fc ' 逐一取出子資料夾物件放到 f1 變數中
    mydate=year(f1.DateLastModified) & "/" & month(f1.DateLastModified) & "/" & day(f1.DateLastModified) ' 重組日期字串的格式,以方便顯示
    if date()-f1.DateLastModified <= 6 then ' 檢查是否為一週內的檔案
        mynew=mydate & "<font color=red size=1>new<br>" ' 若是,則在檔名後方寫一個 new 來加強標示
    else
        mynew=mydate & "<br>" ' 若否,僅顯示檔名
    end if
    if left(f1.name,1) <> "_" and f1.name<>"manager" then ' 避開 frontpage 自動產生的 _ 開頭的目錄及本程式使用的 manager 目錄,這些目錄將被隱藏不顯示,其餘符合條件的目錄則繼續進行後續處理
        i=i+1 ' 首先將計數器加一  
        response.write("<td style='font-size:9pt' align=center width=75><a href='index.asp?dir=" & mydir & "/" & f1.name & "' onmouseover=document.all['" & f1.name & "'].src='manager/folder2.gif'; onmouseout=document.all['" & f1.name & "'].src='manager/folder1.gif';><img id='" & f1.name & "' src=manager/folder1.gif border=0><br>" & f1.name & "</a><br>" & mynew & chr(13)) ' 顯示目錄小圖示、超連結和目錄名稱...等相關訊息
        if i mod 6 = 0 then ' 已經顯示的子資料夾數量是否為 6 的倍數
            response.write("</tr><tr>") ' 若是,則換行
        end if
    end if
next
%>
</tr></table><table border=0><tr>
<%
i=0 ' 將檔案計數器再度歸零
if mynumber<=0 then mynumber=6 ' 檢查每行要顯示的圖檔數是否為 0 或小於 0,若是,則預設顯示六張圖
for each f1 in fl ' 逐一取出檔案物件放到 f1 變數中
    extname = f.GetExtensionName(realpath & "/" & f1.Name) ' 讀取附加檔名
    mydate=year(f1.DateLastModified) & "/" & month(f1.DateLastModified) & "/" & day(f1.DateLastModified) ' 重組日期字串的格式,以方便顯示
    if date()-f1.DateLastModified <= 6 then ' 檢查是否為一週內的檔案
        mynew="K<img src=manager/new.gif><br>" ' 若是,則以動態圖檔來加強標示
    else
        mynew="K<br>" ' 若否,不用加強標示,直接換行
    end if
    i=i+1 ' 將檔案計數器加一
    if f1.Name="message.htm" then ' 避開 message.htm 不顯示
        i=i-1 ' 此檔案不算數,因此將計數器減一
    elseif Ucase(extname)="MID" or Ucase(extname)="RMI" or Ucase(extname)="AU" or Ucase(extname)="WAV" then ' 檢查附加檔名是否為音樂類型的檔案
        response.write("<td style=font-size:9pt align=center width=75><a href=" & mydir & "/" & f1.name & ">" & f1.name & "</a><br>" & int(f1.size/1024) & "K<br><embed src=" & mydir & "/" & f1.name & " autostart=false loop=false width=75 height=20>" & mynew & chr(13)) ' 此類檔案顯示小圖示而非縮圖
    elseif Ucase(extname)="GIF" or Ucase(extname)="JPG" or Ucase(extname)="JPEG" or Ucase(extname)="PNG" then ' 檢查附加檔名是否為圖形檔
        z = InStr(mydir,"背景") ' 在路徑字串中搜尋 背景 關鍵字
        if z>0 then ' 如果有找到,則允許動態切換背景,進行底下後續處理
            if mywidth=0 and myheight=0 then ' 檢查是否未指定縮圖大小
                response.write("<td style='font-size:9pt' align=center width=75><a href=javascript:bgpic('" & mydir & "/" & f1.name & "')><img src=" & mydir & "/" & f1.name & " border=0 onmouseclick=bgpic('" & mydir & "/" & f1.name & "')><br>" & f1.name & "</a><br>" & int(f1.size*100/1024)/100 & mynew & chr(13)) ' 以原圖大小顯示圖檔,並設定 onmouseclick 事件,以便進行背景圖切換
            elseif mywidth>0 and myheight=0 then ' 是否僅指定縮圖寬度
                response.write("<td style='font-size:9pt' align=center width=75><a href=javascript:bgpic('" & mydir & "/" & f1.name & "')><img src=" & mydir & "/" & f1.name & " border=0 width=" & mywidth & " onmouseclick=bgpic('" & mydir & "/" & f1.name & "')><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 以寬度為基準來縮放圖檔,並設定 onmouseclick 事件,以便進行背景圖切換
            elseif myheight>0 and mywidth=0 then ' 是否僅指定縮圖高度
                response.write("<td style='font-size:9pt' align=center width=75><a href=javascript:bgpic('" & mydir & "/" & f1.name & "')><img src=" & mydir & "/" & f1.name & " border=0 height=" & myheight & " onmouseclick=bgpic('" & mydir & "/" & f1.name & "')><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 以高度為基準來縮放圖檔,並設定 onmouseclick 事件,以便進行背景圖切換
            else ' 其餘情形,也就是縮圖的寬度和高度都有指定時
                response.write("<td style='font-size:9pt' align=center width=75><a href=javascript:bgpic('" & mydir & "/" & f1.name & "')><img src=" & mydir & "/" & f1.name & " border=0 width=" & mywidth & " height=" & myheight & "><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 以指定方式縮放,有時候會造成圖檔變形,設定 onmouseclick 事件,以便進行背景圖切換
            end if
        else ' 找不到 背景 關鍵字時,不作背景圖切換,改為顯示原圖,處理方式如下
            if mywidth=0 and myheight=0 then ' 檢查是否未指定縮圖大小
                response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=" & mydir & "/" & f1.name & " border=0><br>" & f1.name & "</a><br>" & int(f1.size*100/1024)/100 & mynew & chr(13)) ' 以原圖大小顯示圖檔
            elseif mywidth>0 and myheight=0 then ' 是否僅指定縮圖寬度
                response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & " target=" & f1.name & "><img src=" & mydir & "/" & f1.name & " border=0 width=" & mywidth & "><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 以寬度為基準來縮放圖檔
            elseif myheight>0 and mywidth=0 then ' 是否僅指定縮圖寬度
                response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=" & mydir & "/" & f1.name & " border=0 height=" & myheight & "><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 以高度為基準來縮放圖檔
            else ' 其餘情形,也就是縮圖的寬度和高度都有指定時
                response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=" & mydir & "/" & f1.name & " border=0 width=" & mywidth & " height=" & myheight & "><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 以指定方式縮放圖檔,有時候會造成圖檔變形
            end if
        end if
    elseif Ucase(extname)="HTML" or Ucase(extname)="HTM" then ' 檢查附加檔名是否為網頁檔
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/ie.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="DOC" then ' 檢查附加檔名是否為 Word 文字檔
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/doc.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="PPT" then ' 檢查附加檔名是否為簡報檔
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/ppt.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="EXE" or Ucase(extname)="BAT" or Ucase(extname)="COM" then ' 檢查附加檔名是否為執行檔
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/exe.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="MDB" then ' 檢查附加檔名是否為資料庫檔案
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/mdb.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="XLS" or Ucase(extname)="CSV" then ' 檢查附加檔名是否為 Excel 檔案
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/xls.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="BMP" or Ucase(extname)="UFO" then ' 檢查附加檔名是否為 BMP UFO 圖檔
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/gif.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="TXT" or Ucase(extname)="" or Ucase(extname)="" then ' 檢查附加檔名是否為純文字檔案
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/text.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="MPG" or Ucase(extname)="MPE" or Ucase(extname)="AVI"then ' 檢查附加檔名是否為影音檔
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/mpg.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="ZIP" then ' 檢查附加檔名是否為壓縮類型的檔案
        response.write("<td style='font-size:9pt' align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/zip.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 顯示小圖示
    elseif Ucase(extname)="ASP" or Ucase(extname)="BAK" then ' 檢查附加檔名是否為 ASP 程式或其備份檔
        i=i-1 ' 此檔案不顯示,因此將計數器減一
    else
        response.write("<td style=font-size:9pt align=center width=75><a href=" & mydir & "/" & f1.name & "><img src=manager/other.gif border=0><br>" & f1.name & "</a><br>" & int(f1.size/1024) & mynew & chr(13)) ' 不認識的檔案類型顯示系統預設小圖示
    end if
    if i mod mynumber = 0 then response.write("</tr><tr>") ' 檢查是否已到達該換行的數量,若是,則換行
next
%>
</tr></table>
<hr width="90%" color="#FF0000">
<p align="center" style="margin-top: 0; margin-bottom: 0">
<% if mydir = "." then %>
<a href="./"><img src=manager/uplevel.gif border=0>回首頁</a>
<% else %>
<a href="index.asp?dir=."><img src=manager/menu.gif border=0>回目錄</a> <a href="index.asp?dir=<% =uplevel %>"><img src=manager/uplevel.gif border=0>回上一頁</a>&nbsp;
<% end if %>
</BODY>
 

(二十六)、#INCLUDE  的用法

  您可在現有的ASP程式中,插入另外一個「被包括」的檔案,執行到此處時先執行此「被包括」的檔案後,再繼續執行下一行的程式碼。使用的是「#INCLUDE」的語法,語法如下:

 其中VIRTUAL代表虛擬的檔案位址,FILE代表絕對的檔案位址,如下:

 附加檔案名稱建議使用.inc,但是也可以使用任何附加檔案名稱。您可使用FILE和「../ 」代表上一層的檔案目錄。「#INCLUDE」的語法,適用於多個網頁共同使用的部份,有點像副程式,供多個ASP程式碼呼叫使用。

(二十七)、Cookies存取寫在用戶端瀏覽器的方法

  使用 Cookies,可讓您於用戶端的硬碟上儲存一些資訊,譬如當來訪者輸入其姓名、EMAIL、密碼等資料時,使用Cookies將之儲存於來訪者用戶端的瀏覽器(硬碟)上,下次這位來訪者再度瀏覽此網站時,即可讀取此Cookies直接得知來訪者的身份。

ASP 存取讀寫 Cookies 的方式,係使用ASP 兩個內建的「物件」Response 和 Request,十分簡單,如下:

寫入Cookies:

讀取Cookies:


 

肆、ODBC 連結機制

  當我們開始開發資料庫應用程式時,須先熟悉 ADO 物件中的子物件:Connection。

  Connection 物件用來建立程式與資料庫之間的連結。這種連結方式是國際通用的標準,稱為 ODBC(Open DataBase Connection)。

  Connection 物件最重要工作,是把 ASP 程式中的連結字串(Connect String)傳送給 ODBC 處理,ODBC 收到後,剖析該字串,並且使用專有的 TCP / UDP 通訊協定來與資料庫溝通(MsSQL:1433Port/MySQL:3306Port )。

  這個資料庫連結的字串,必須包含建立連結時所需要的一切資訊,像是:資料庫種類、Server 名稱、資料庫名稱、登入的帳號密碼和認證方式、資料型態設定(語系、數字、貨幣設定...等等)。

  當連結建立成功之後,Connecting 物件就會把這些資訊保留在記憶體內,以便隨時維護連線不使它中斷。

  ODBC 是國際標準,所有的資料庫都有支援。透過 ODBC 這個服務,您可以跨平台連結任何不同品牌、類別的後端資料庫。例如:我們想連結 mySQL,那麼只要安裝 myODBC 的函式庫到我們的電腦上面,就可以在 ASP 裡面以 Connection 物件來存取 mySQL 資料庫。

  早期ASP程式設計師使用 DSN (Data Source Name)來連結資料庫,DSN 檔案的內容是純文字,內含資料庫類型、路徑甚至開啟資料庫的帳號、密碼,因為太容易被使用者猜出、下載,對系統安全影響甚鉅,所以不再被程式設計師愛用。

  大部分的做法是把 DSN 的檔案內的〝連結字串〞,直接寫在 ASP 程式碼中。這樣做的好處是,當程式移植到另一台主機時,只要對連接字串進行小修改甚至是不需修改,就可以直接執行,遷移性非常強。

  由於一個完整的資料庫應用程式,由多個 ASP 程式組成,每段程式進行資料庫存取時,都需透過 ODBC 建立資料庫連結,這會造成資料庫開開關關,同一程序反覆執行的後果,而使得資料庫存取的效能變差。因此比較好的做法是在資料庫連結建立後,將 Connection 物件保存在 Application 物件內,如此一來,資料庫連結將與站台永遠同在,執行效能當然也會變好。

  但是,如果把少用而多量的資料庫連結存放在 Application 物件內,也會導致伺服器效能急速下降,必須重開機才能釋放資源,反而得不償失。

  在新版的 IIS 伺服器上,支援 Connection pool 功能,也就是說即使 ASP 程式將 Connection 物件關閉了,但是它並不會真正消失,而會保留在記憶體區塊(pool)裡面(並非 Application 物件),等下次再開啟資料庫時,直接回存連結物件而不是重新建立連結,這樣就會讓初學者的 ASP 程式的表現比較專業!

(一)、使用資料庫--ADO物件

  當我們開始撰寫需要存取到資料庫的ASP程式時,就需要學會怎樣使用 ADO(ActiveX Data Ojects) 物件了。它是WEB程式存取資料庫的介面。ADO物件的簡易模型如下:

(二)、ADO物件的相關物件和屬性

物件 屬性/方法
Connection 物件

準備執行SQL指令前要先開啟資料連結做準備

ConnectionString,CommandTimeout , Mode

Open, Close, Execute

Command 物件

定義想要執行的SQL指令

CommandText , CommandType , CommandTimeout

Execute

Paramter物件 伴隨SQL指令的參數
RecordSet 物件

使用Connection開啟的資料錄

AbsolutePage,AbsolutePosition,ActiveConnection,Bookmark,CacheSize, EditMode, EOF, BOF, MaxRecords, PageCount, PageSize,RecordCount,

RecordSet 中的 CursorType:Dynamic/keyset/static/Forward-only

AddNew ,Close , Delete , GetRows , Move , MoveFirst , MoveLast , MoveNext , MovePrevious , Open ,Update

Fields 物件 RecordSet 物件中的欄位
Errors 物件 ADO連結有錯誤時儲存錯誤訊息用的物件
Property 物件 內含ADO的特性,有內建與動態兩種類型

 

(三)、存取資料庫步驟

動  作

範    例

建立ADO物件的連結

Set conn = Server.CreateObject("ADODB.Connection")

第一步

取得資料庫路徑

DBPath = Server.MapPath("ysps.mdb")

指定資料庫驅動程式類型

driver={Microsoft Access Driver (*.mdb)};

開啟資料連結

conn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & DBPath

產生資料錄

Set rs = Server.CreateObject("ADODB.Recordset")

第二步

以SQL語法選取資料內容

查詢語法

SQLString="SELECT * FROM my_table Where my_no>2"

新增資料

SQLString="Insert into my_table(my_no,my_name) values(20,'dd')"

刪除資料

SQLString="delete * from my_table where my_no=10"

修改

SQLString = "Update my_table set my_tel = '28975966' where my_name='dd' "

執行SQL字串

conn.excute("SQLString")

讀寫資料錄[RecordSet物件]各種屬性操作,也許利用到各類迴圈和判斷式

RecordSet 的各種屬性

RS.Fields.Count:RecordSets 的欄位數。

RS(i).Name:第 i 個欄位名稱,i 由 0 算起到 RS.Fields.Count-1。

RS(i):讀取第 i 個欄位的資料,i 由 0 算起到 RS.Fields.Count-1。

RS(“欄位名稱”):讀取指定欄位的資料。

RS.EOF:是(True)否(False)已指到最末筆。

RS.MoveNext:將指標移到下一筆。

RS.MovePrev:將指標移到上一筆。

RS.MoveFirst:將指標移到第一筆。

RS.MoveLast:將指標移到最末筆。

RS.GetRows:將查詢結果存於陣列當中,如 v=RS.GetRows(100),再讀取陣列 v(col,row) 的值即為查詢的資料。

RS.Properties.Count:得知 ADO 的 Connection 或 Resultset 之屬性總數。

RS.Properties(Item).Name:得知 ADO 的 Connection 或 Resultset 之屬性名稱。

RS.Properties(Item):得知 ADO 的 Connection 或 Resultset 之屬性值。

最後,顯示後使用如下的指令,關閉資料庫:

RS.Close

Conn.Close

 

關閉資料錄

rs.close

第三步

關閉ADO連結

conn.close
 

 

(四)、 把連結字串放入global.asa中的 Application變數,便於日後取用

  前四項開啟資料庫連結的處理上,比較好的解決辦法是把資料庫的連結字串[Connection String],放入你的根目錄[或虛擬目錄]下的 global.asa 中,讓它變成 application 在記憶體中常駐,看起來像這樣:

 

<SCRIPT LANGUAGE=VBScript RUNAT=Server>

Sub Application_OnStart
'以下此行設定資料庫來源 請改為正確路徑
Application("ysps1") = "Driver={SQL Server};Server=ysps1;database=JSDB;uid=SYSUSER;pwd=SYSUSER"
Application("spps") = "Driver={SQL Server};Server=ysps1;database=spps;uid=SYSUSER;pwd=SYSUSER"
Application("board") = "Driver=driver={Microsoft Access Driver (*.mdb)};dbq=d:\inetpub\wwwroot\board\board.mdb;PWD=123456"
END SUB
</SCRIPT>

 

然後修改所有的asp程式碼,讓資料庫使用這個application。程式中開啟資料庫連結的寫法精簡一些,但效能卻好多了:

一般的寫法:
Set conn = Server.CreateObject("ADODB.Connection")
DBPath = Server.MapPath("/database/ysps.mdb")
conn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & DBPath

使用Application的寫法:
Set Conn = Server.CreateObject("ADODB.Connection")
conn.open Application("ysps1")

 

(五)、global.asa裡面放開啟資料庫的密碼安全嗎?

點這裡試試看你抓得到我的global.asa嗎?

其實是抓不下來的,您會看到以下的畫面:(http 錯誤 500-15 )

IIS server 是不允許您存取該檔案的,所以在安全上並沒有問題。


 

SQL 語法概說

  SQL 是「結構化查詢語言」(Structured Query Language)的簡稱,是由 IBM 公司於 1970 年代所發展出來,用於關連式資料庫 (Relational Databases) 當中的一種資料庫查詢語言,利用 SQL 可以用來定義資料庫結構、指定資料庫表格與欄位型態與長度、新增資料、修改資料、刪除資料、查詢資料,以及建立各重複雜的表格關連,成為一個查詢資料庫的標準語言。

    雖然各家資料庫所提供的 SQL 語法在功能上會略有差異,但基本的功能都是符合于ANSI SQL的。SQL 的設計基本上是模仿英文的自然語法,因此在入門上較為容易。

    SQL指令最常用的四個基本查詢動作,即:瀏覽(查詢)、新增、修改、刪除,因此將來所設計的 Web asp程式,也通常會包含這四種功能。

(一)、查詢資料: 若要查詢資料庫的資料,使用的 SQL 指令是「SELECT」,基本語法如下:

SELECT 欄位名稱1,欄位名稱2... FROM 資料表名稱1,資料表名稱2... WHERE 條件式 ORDER BY 欄位名稱1  DESC(降冪排序),欄位名稱2...

  • SELECT:所接的欄位名稱為待查資料庫的欄位名稱,各欄位名稱之間以逗號隔開。
    FROM:所接的資料表名稱為待查資料庫的資料表名稱,各資料表名稱之間以逗號隔開。
    WHERE:設定查詢的條件式。
    ORDER BY: 設定要排序的欄位名稱,可將查詢的資料依照想要排序的資料表欄位加予排序,指定多個欄位時,就要以欄位名稱1排序,若其資料相同則再依欄位名稱2排序,依此類推,各欄位名稱之間以逗號隔開。

  • 範例如下:

SQLString = "select * from DEMP order by SEX desc,NAME

→選取DEMP這個資料表的所有內容,並先照性別降冪排序(男生排前面),再依照姓名筆劃排序

在進行條件比對時,如果比對的欄位是數字欄位,則不加識別符號,例如:where money >= 3000,如果該欄位為文字欄位,必須使用 ' 來標示,例如:where NAME = '張三',如果是比對日期欄位,則用 # 來標示,例如:where post_date >= #2003/04/15#

常用的條件判斷還有:

  1. 文字欄位模糊比對:使用 Like 敘述配合 % 符號來比對,例如:比對第一個是否為 ""where NAME Like '%',比對結尾是否為 ""where NAME Like '%',比對是否含有 ""where NAME Like '%%'

  2. 集合比對:比對欄位的值是否為集合中所列舉的其中一個,這可以運用在任何資料類型的欄位上,範例如下:

SQLString = "select * from BCLASS where SYEAR='" & stryear & "' and SEME='" & strseme & "' and left(CLASSNO,1) in ('3','4','5','6') "

→選取BCLASS資料表內的所有資料但是SYEAR必須 = stryear變數的值(學年),且SEME必須 = strseme變數的值(學期),且CLASSNO(班級代號)為 3,4,5,6 其中任一個字元

 

合併查詢:當資料分布在多個資料表中,就必須使用合併查詢,合併查詢意思是將兩個資料表先合併成一個,然後再進行條件過濾,篩選出想找的資料記錄,依照合併方式的不同,又分為外部合併(outter join)和內部合併(inner join),假設有兩個資料表,前者有十筆紀錄,後者也有十筆紀錄,兩者以學號來互相關聯,進行外部合併時,會將兩個資料表相乘,得到一個 100 筆紀錄的新資料表,接著再逐筆過濾學號是否一樣;如果進行內部合併,則先以學號作為索引,將兩資料表中相同索引的紀錄合併為一筆,最後得到一個十筆紀錄的資料表。

  由於內部合併比較省記憶體,而且如果欄位索引事先已經做好,其合併效能遠高於外部合併,因此底下僅介紹內部合併的方法:

SQLString = "select A.CLASSNO,A.SEAT,B.NAME,B.SEX from BSTD_SEME A join BSTD B on A.STDNO=B.STDNO where A.SYEAR='" & stryear & "' and A.SEME='" & strseme & "' and A.STD_STATUS='1' and right(B.BIRTHDAY,4) = '" & my_today & "' order by A.CLASSNO"

→把BSTD_SEME 這個資料表命名為 A,把BSTD 這個資料表命名做 B,我要以 A、B 資料表裡面都有的 STDNO 欄位(學號)當作索引來合併資料表。並篩選出 A 的學年期和現在的學年期相等,而且學生的狀況為在學 (A.STD_STATUS='1') 的學生,而且 B 資料表上的 BIRTHDAY 欄位的後四碼是今天,找出來以後照年級來排序。

 

 注意:當在 ASP 程式中組合 SQL 敘述時,通常會使用變數來代入比對條件,這時候必須將 SQL 字串與變數連接起來,方法是先用雙引號來標示兩段字串的範圍,然後用〝&〞符號來連接字串,特別是在SQL 敘述中進行文字欄位的比對時,不要忘記在變數值的前後,額外多用單引號來標示,此單引號為 SQL 語法的一部分,因此必須放在雙引號之內。

   通常我們會先把整句SQL語法寫完整後,然後再將變數逐個放入整個SQL字串內,這樣一來就不容易出錯。

偵錯:當我們執行SQL語句發生錯誤時,會先把程式中的SQL字串印在網頁上,然後中止程式。例如:

SQLString = "select * from BCLASS where SYEAR='" & stryear & "' and SEME='" & strseme & "'"

response.write SQLString

response.end

        作業:請找出底下的語法哪裡錯誤:

        SQLString = "select * from SEMP where NAME = '" & firstname & "%' and EMPID=" & strid

 

(二)、新增資料: 若要新增資料庫的資料,使用的 SQL 指令是「INSERT」,基本語法如下:

INSERT INTO 資料表名稱(欄位名稱1,欄位名稱2,...) VALUES ('欄位1的資料','欄位2的資料',...)

SQL= " INSERT INTO MY_TABLE(NAME,PHONE,ADDRESS,BIRTH) VALUES ('黃自強','28975966','新民路2號','19940101')"

有變數的話:

SQLString = "INSERT INTO BITEM_SCORE  (SYEAR,SEME,EMPNO,ITEM,SUBJNO,STDNO,SCORE)
Values('" & stryear & "','" & strseme & "','" & strempno & "','" & stritem & "','" & strcur & "','" & X & "'," & Request(X) & ")"

SQL字串太長可以分成兩段來連接:

SQLString = "Insert into award_question (id,grade,question,correct,start_date,end_date,post_date) values ("

SQLString = SQLString & id & "," & grade & ",'" & quiz & "','" & correct & "','" & sdate & "','" & edate & "','" & pdate & "')"
 


(三)、修改資料: 若要修改資料庫的資料,使用的 SQL 指令是「UPDATE」,基本語法如下:

UPDATE 資料表名稱
SET 欄位名稱1=欄位1的資料,欄位名稱2=欄位2的資料,... WHERE 條件式

SQL= "UPDATE  MY_TABLE SET NAME='黃自強' WHERE PHONE='28975966' AND BIRTH='640101' "

sql = "Update award_question set grade=" & grade & ",question='" & quiz & "',correct='" & correct & "',start_date='"
sql = sql & sdate & "',end_date='" & edate & "',post_date='" & pdate & "' where id=" & id
 

 

(四)、刪除資料: 若要刪除資料庫的資料,使用的 SQL 指令是「DELETE」,基本語法如下:

DELETE FROM 資料表名稱 WHERE 條件式

sql = "Delete from award_question where id=" & id
 

sql = "Delete BITEM_SCORE Where SYEAR='" & stryear & "' and SEME='" & strseme & "' and STDNO='" & X & "' and SUBJNO='" & strcur & "' and EMPNO='" & strempno & "' and ITEM='" & stritem & "'"
 


(五)、注意事項:ASP使用SQL語法存取資料庫時,請參考下列注意事項:

(六)、關於SQL隱碼攻擊

  前一陣子很紅的SQL隱碼攻擊事件,曾經讓無數的程式設計師和網管人員晚上睡不著覺,徹夜修改程式碼。

  這個讓全世界緊張的事件,其實不能算是ASP程式的 bug,而應該說是〝刻意辜負人家的善意〞。

  程式設計師撰寫網頁應用程式時,假定所有的使用者,都是善意的,正常人在表單填入的文字,並不會用 SQL 語法或控制字元,於是並不會多做檢查。駭客就利用 這個善念漏出來的漏洞入侵。入侵者利用這個漏洞,可以很容易的透過網頁,取得資料庫中的信用卡號等敏感資料,也能取得資料庫管理權限,甚至下載資料後,刪除、破壞資料庫,再對受害者加以勒索。

詳細資料請參考:SQL資料隱碼攻擊與防堵方法

  更慘的是如果系統管理員一直沒有把 IIS 的漏洞修補、更新好,留下一堆漏洞,駭客就還可以再遠端上傳木馬程式,並且透過網址列執行木馬程式,或是在您的主機上建管理員帳號、改權限,更狠的會刪除整個硬碟....等。而在自由、民主、開放的國家,這些簡易入侵的方法,何x仁書店就買的到。

  我們要避免這類型的駭客手法,可以從幾方面著手:

' ------自動寄發email-----
if hackip_count>5 and instr(id,"'")  then
    hackip =
Request.Servervariables("Remote_Addr")
    Set Mail=Server.CreateObject("CDONTS.NewMail")
        mail.MailFormat=1
        mail.BodyFormat=1
        Mail.From = "xxps@xxps.tp.edu.tw"
        Mail.to = "net110@net110.gov.tw;admin@mail.xxps.tp.edu.tw"
        Mail.Subject = "檢舉駭客入侵"
        Mail.Body = "入侵時間" & now() & "入侵者ip:" & hackip & "事項:...檢舉人:....XX國小網路中"
        Mail.Send
        Set Mail=Nothing

    ' ------自動寄發email結束-----

response.write "您的入侵行為和紀錄,依法已經送交網路警察局處理,請好自為之。"
end if
或是直接傳值給台北市警察局網站網路報案用的表單:

response.redirect " http://safety.taipei-elife.net/postcase.asp?title=檢舉入侵&body=......略....."
(以上的舉例欄位,都不是真的,請勿套用)

(七)、以MS-SQL Server 作為後端資料庫實做

  在熟練使用 ACCESS 資料庫後,進階的練習就是以 MS-SQL 2000 Server 作為後端資料庫。網路抓來的ASP程式,多半是使用Access 97~2000的 MDB檔案作為後端資料庫,好處是遷移性強,檔案下載回去,換個主機拷貝進去,如果資料夾名稱沒便,只要把檔案權限設定一下,馬上就可以上線工作。但是相對也有缺點。

  缺點是同時上線存取資料庫的連線數量不能太多,否則會發生資料庫開啟失敗的情況,也就是說以MDB作為資料庫適合一般流量不大的網站,像班級網站。需應付大量(約100人)使用者同時瞬間上線,像是每天有數千人參觀的熱門網站,就比較不適合。

  依經驗推估每天網站訪客人數超過1000人的網站,或是網頁設計上有應用程式的功能是經常要更新(網頁經常需要自動 Reload的網頁),就建議您使用MS-SQL Server。或者安裝免費的 Apache For Win32 + MySQL + PHP 等軟體來開發互動網頁,也是不錯的選擇。新版的BigApache套件也同時支援ASP。

BigApache (for Win32)提供包括 Html / PHP / Pearl / ASP / JSP / Java / MySQL 的Web 伺服站所有相關程式及設定。

  透過網路上任意一台WEB SERVER 存取 SQL Server上的資料庫的反應的速度和效能,都比存取MDB資料庫高太多了。尤其在複雜的多資料表結合查詢,更顯出SQL的威力。使用MS-SQL 2000 Server還有一個好處,就是不必擔心資料庫會被使用者刻意下載回去,造成網站安全漏洞。

  使用缺點就是MS-SQL Server 2000 實在是太貴了,網路使用還要購買足夠的網路使用者使用權才行 ,還好台北市各校在校務行政的標案中,有MS-SQL 6/7/2000 Server的授權,不必再多花錢另外購買,而且只Web Server 上的程式存取,只算一人份的使用者授權。


  下面的內容以實做方式介紹怎樣使用SQL Server來建立和使用資料庫。

作業:寫一套〔網站有獎徵答〕的程式,提供校內老師都可以出題,所有學生可挑選適合的問題來回答。

  題目是以學校推動的宣導事項、圖書館利用教學、網路查資料等主題為主。以這個有獎徵答的程式寫作計劃來看,我們開發這一套程式的〝手順〞可以安排成:

繪出程式運作流程 → 設計資料庫 → 設計網頁介面 → 填入ASP 程式碼 → 實際測試程式

寫作ASP程式的步驟建議如下:

  1. 繪製程式運作流程圖,即使隨手只能取到餐巾紙。

  2. 根據程式需求,設計資料庫的table 名稱、欄位名稱、各欄位的資料型態、索引鍵值...等相關設定。

  3. 先用FrontPage等WYSWYG網頁編輯軟體把會用到的網頁純 html 使用者介面線設計好,例如:清單、新增、刪除、修改等網頁。

  4. 開始撰寫(填入)ASP程式碼。

  5. 測試程式。

  6. 美工配色等美化工程(通常交給美工管理人員)。

  1.繪製流程圖:

 

2.設計有獎徵答的資料庫

程式架構好了以後要做的就是把需要用的資料表設計完成。要直接用SQL Server 開發資料庫程式的話,我們需要到 SQL Server 主機上開資料庫和設計資料表,或使用遠端遙控軟體來開設資料庫。

請到有安裝 SQL Server 的機器上,從開始功能表開啟 SQL Enterprise Manager (企業管理員),並按滑鼠右鍵,新增一個資料庫,例如:spps(spps是石牌國小的縮寫,資料庫名稱設為石牌國小的好處是:以後去石牌國小抓回來的ASP套件,不用改什麼程式碼,就可以直接套用,當然您想改換名稱也是可以的)。

我們可以看到資料庫產生完成的畫面:

接下來手動建立程式需要的兩個新資料表:

根據程式提供的功能所需,設計各個資料的欄位屬性.例如:

  • ID-每個題目有一個ID,它也同時是鍵值。而且是唯一的、不能修改的。資料型別為整數(int),長度為4,不允許空值(null)。這裡的ID代表學生選答的題目編號。

  • stuno-nvarcher /12 / not null /學生學號

  • classno-char / 5 / not null / 學生班級

  • student-nvarchar / 12 / not null /學生姓名

  • answer-nvarchar / 100 /學生填的答案

  • correct-bit / 1 / not null /是否正確

  • ans_date-datetime / 8 / not null /學生填答的日期

關閉時會問:

請將這個資料表命名為award_answer

另外再依照以下範例,設計另一個老師出題用的資料表:

  • id / 題號

  • grade / 題目給低中高年級哪個年級答? 全校:0、 低年級:1、中年級:2、高年級:3

  • question / 老師出的題目內容

  • correct / 正確答案

  • start_date / 開始日期

  • end_date / 結束日期

  • post_date / 張貼日期

  • mum / 本題填答的學生數量

 

3.有獎徵答網頁介面設計

    我們需根據程式運作流程圖,來設計製作各個頁面:

ASP檔名 功能
/award/default.asp 主網頁:秀出目前的題目/登入按鈕/管理員可新增題目。學生可登入/選答/看排行榜連結
/award/sort.asp 目前已經結束徵答的答對的學生他們的答對次數排行榜
/award/list.asp 列出某一題目答對的學生他們的答對次數排行榜
/award/manager.asp 列出老師能新增、刪除、和修改問題的表單,點題目的話可以審核學生的答案是否正確
/award/addnew.asp 新增有獎徵答的問題用的表單,需有題目、答案、張貼日、開始日期、結束日期等資訊
/award/delete.asp 刪除一題
/award/edit.asp 編輯已經出過的題目、答案和日期
/award/check.asp 列出學生回答的答案,來讓老師查核學生答案的程式
/award/answer.asp 學生填寫答案的表單頁面
/award/thankx.asp 感謝語,寫入學生回答的答案、自動寄發電子郵件給管理老師的程式
/award/save.asp 新增和修改資料後存入資料庫的程式
/check.asp 檢查使用者id和password的表單
/check2.asp 利用校務行政資料庫來比對老師、學生的帳號密碼,和認證的Session處理

請先把下面幾個ASP網頁介面製作完成:

default.asp  有獎徵答首頁


 (介面的html檔)

<html><head><title>有獎徵答</title></head>
<body>
<table id="AutoNumber1">
<tr>
<td><h1>《網路有獎徵答》</h1></td>
<a href="manager.asp"></a></td>
</tr>
<tr>
<td><font size="3" color="#385B96">§ <a href="sort.asp">得獎排行榜</a></td>
<td><a href="manager.asp">管理</a>
</td>
</tr>
</table><center>
<table border="1">
<tr><td>期別</td><td>對象</td><td>題目</td><td>活動期限</td><td>活動</td></tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>
<a href="answer.asp?id=1">我要答</a><br>
<a href="list.asp?id=1">得獎名單</a>
</td>
</tr>
</table></center></div></body></html>

 

manager.asp:老師的管理頁面

(html檔)

<html><head><title>有獎徵答</title></head>
<body>
<h1 align="center">管理選項</h1>
<a href="default.asp">回有獎徵答首頁</a>

<table border="1">
<tr><td>期別</td><td>對象</td><td>題目(點題目審閱)</td><td>作答人數</td><td><a href="addnew.asp">新增題目</a></td></tr>
    <tr>
        <td> </td>
        <td> </td>
        <td><a href=checkit.asp?id=1>這裡是題目</a> </td>
        <td> </td>
        <td>
            <a href=edit.asp?id=1>修改</a> 
            <a href=delete.asp?id=1>刪除</a><br>
            <a href=list.asp?id=1>得獎名單</a>
    </td>
    </tr>
</table>
<a href="default.asp">回有獎徵答首頁</a>
</center></body></html>

 

addnew.asp :新增題目

<html><head><title>新增題目</title></head>
<body><h1 align="center"><font face="標楷體">新增題目</h1>
<hr>
期有獎徵答
<form method="POST" action="save.asp">
<input type=hidden name=id value="<% =id %>">
<table border="2" cellspacing="1">
<tr><td >適用階段</td>
<td >
    <select size="1" name="grade">
        <option value="0">低年級</option>
        <option value="1">中年級</option>
        <option value="2">高年級</option>
        <option value="3">全校</option>
    </select>
</td></tr>
<tr>
<td >題目是</td>
        <td><textarea rows="5" name="quiz" cols="33"></textarea> </td>
</tr>
<tr><td>正確答案</td><td ><input type="text" name="correct" size="35"></td></tr>
<tr><td >開始日期</td><td >
        <select size="1" name="syear">
                    <option value="1">1</option>
        </select>年

        <select size="1" name="smonth">
                     <option selected  value="1">1</option>
        </select>月

        <select size="1" name="sday">
            <option selected value="1">1</option>
        </select>日
</td></tr>
<tr><td >結束日期</td>

<td >

        <select size="1" name="syear">
                    <option value="1">1</option>
        </select>年

        <select size="1" name="smonth">
                     <option selected  value="1">1</option>
        </select>月

        <select size="1" name="sday">
            <option selected value="1">1</option>
        </select>日

</td></tr>
<tr>
<td >公告日期</td>
<td >
        <select size="1" name="syear">
                    <option value="1">1</option>
        </select>年

        <select size="1" name="smonth">
                     <option selected  value="1">1</option>
        </select>月

        <select size="1" name="sday">
            <option selected value="1">1</option>
        </select>日

</td> </tr> </table> </center>

<p align="center">
<input type="submit" value="存檔" name="B1"> <input type="reset" value="重寫" name="B2"></p>
</form>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p></body> </html>

 

save.asp : 各種動作的存檔程式

<%   ' 權限判斷

  ' 去除使用者輸入的表單傳來的資料中,潛藏有 SQL 隱碼攻擊可能的單引號字串
  ' 因為表單上使用國曆年給管理人員點選,寫入資料庫時,必須改為西元,因此要經過轉換、再把年月日連接起來,交給變數
  ' 根據表單傳來的資料,組合 SQL 語法
  ' 如果資料記錄是空的(沒有這個id,表示資料庫中沒有這個題目,動作一定是新增)
  ' 就把後面要執行的sql字串變數,寫成插入新的id、年級、題目、答案、日期等資料到資料表award_question中
  ' 否則就寫成更新資料到資料表award_question中
  ' 執行sql命令
  ' 把網頁轉到〝管理頁面〞
%>

 

answer.asp 學生填答的表單

<html><head><title>我要回答</title></head>
<body>
<h1>我會回答問題</h1>
<hr>
<p><font color="blue">xx小朋友請注意以下規則:</p>
        1.每人只能回答一次,無法反悔改答案<br>
        2.請多利用圖書館或網路尋找答案<br>
        3.請不要替他人作答或洩漏答案,影響比賽的公平性<br>
        4.所有的成績會在期末統計,並頒發獎品給答對最多題目的同學<br>
        5.現有獎品:李忠憲老師提供 PS2 五台 , XBOX 三台 <br>
如果已經回答
        <marquee behavior="alternate">你已經答過這題了,不可以修改或再次作答!          
        </marquee><a href="default.asp">回有獎徵答首頁</a></p>

        本期題目:<br>
        我的答案是:
            <form method="POST" action="thanx.asp">
            <input type="hidden" name="id" value="<% =id %>">
            <textarea rows="5" name="answer" cols="45" >
                我是xxxx,我的答案是:
            </textarea>
    <input type="submit" value="寫好了,幫我儲存" name="B1"> <input type="reset" value="重寫" name="B2"></form>

</body></html>

 

thankx.asp:寫入資料庫並寄發eamil 通知管理老師

---------寄發email部分

<html><head><meta http-equiv='Content-Type' content='text/html; charset=big5'></head>

<body><table border=0>

<tr><td> ■答題學生姓名:</td></tr>
<tr><td>有獎徵答學生填答通知</td></tr>

<tr><td>■學生email:</td></tr>
<tr><td>【題目=xxxxx】學生的答案:</td></tr>

<tr><td>
    <a href = 'http://www.xxps.tp.edu.tw/checkt.asp?topage=/award/manager.asp'>○請出題老師在活動截止前點這裡前往審核○</a>
</td></tr>

<tr><td align=right><font color= red >寄發時間:</tr></table>

---------寄發email部分

---------網頁部分
<html><head><title>謝謝您的作答</title></head>
<body>
<h1 align="center">謝謝您參加xx國小有獎徵答作答</h1>
<hr>
<p align="center"><b><font color="#385B96">您的答案已經存入資料庫,請等待截止日期老師審查 ,於[結束日期]後才會公佈正確答案及得獎名單!並於期末頒獎</b></p>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p>
</body></html>
---------網頁部分

 

edit.asp : 出題老師編修題目用 (和addnew.asp很像,可以複製addnew.asp來修改)

<html><head><title>編修題目</title></head>
<body>
<h1 align="center"><font face="標楷體">新增題目</font></h1><hr>
期有獎徵答

<form method="POST" action="save.asp">
<input type=hidden name=id value="1">
<div align="center"><center>
<table border="2" cellspacing="1">
<tr>
<td>適用年段</td>
<td>
<select size="1" name="grade">
    <option value="0" selected>低年級</option>
    <option value="1" >中年級</option>
    <option value="2" >高年級</option>
    <option value="3" >全校</option>
</select>
</td></tr>
<tr>
<td>題目是</td>
    <textarea rows="5" name="quiz" cols="33">資料庫裡的題目</textarea>
</td>
</tr>
<tr>
    <td>正確答案</td>
    <td >
    <input type="text" name="correct" size="35" value="正確的答案">
</td>
</tr>
<tr>
    <td bgcolor="#33CCFF"><font color="#FFFFFF">開始日期</font></td>
    <td bgcolor="#CCFFFF">
 
        <select size="1" name="syear">
                    <option value="1">1</option>
        </select>年

        <select size="1" name="smonth">
                     <option selected  value="1">1</option>
        </select>月

        <select size="1" name="sday">
            <option selected value="1">1</option>
        </select>日

</td></tr>
<tr>
        <td bgcolor="#33CCFF"><font color="#FFFFFF">結束日期</font></td>
        <td bgcolor="#CCFFFF">
        <select size="1" name="syear">
                    <option value="1">1</option>
        </select>年

        <select size="1" name="smonth">
                     <option selected  value="1">1</option>
        </select>月

        <select size="1" name="sday">
            <option selected value="1">1</option>
        </select>日

</td></tr>
<tr>
    <td bgcolor="#33CCFF"><font color="#FFFFFF">公告日期</font></td>
    <td bgcolor="#CCFFFF">
        <select size="1" name="syear">
                    <option value="1">1</option>
        </select>年

        <select size="1" name="smonth">
                     <option selected  value="1">1</option>
        </select>月

        <select size="1" name="sday">
            <option selected value="1">1</option>
        </select>日

</td></tr>
</table></center></div>
<p align="center">
<input type="submit" value="存檔" name="B1"> <input type="reset" value="重寫" name="B2"></p>
</p></form>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p>
</body></html>

 

checkit.asp:老師審查答案用

<html><head><title>審閱答案</title></head>
<body>
<h1 align="center"><font face="標楷體">審閱答案</h1><hr>

<table border="2" cellspacing="1">
<tr>
    <td>對  象:</td><td>資料庫裡的哪個年級 </td>
<tr>
    <td>題  目:</td><td>資料庫裡的題目 </td>
</tr>
<tr>
    <td>正確答案:</td><td>資料庫裡的正確的答案 </td>
</tr>
</table>
<table border="2" cellspacing="1">
<tr>
    <td >學號</td><td >班級</td><td >姓名</td><td >答案</td><td >答對</td>
</tr>
<form method="POST" action="update.asp">
<input type="hidden" name="id" value="1">
<tr>
<td>帶出資料庫裡的學號 </td>
<td>帶出資料庫裡的班級 </td>
<td>帶出資料庫裡的姓名 </td>
<td>帶出資料庫裡的答案 </td>
<td>是否答對    <input type="checkbox" name="a" value="ON" checked>
</td></tr>
</table></center>
<p align="center"><input type="submit" value="審核完畢,請幫我儲存" name="B1">

<input type="reset" value="重新審核" name="B2"></p></form></body></html>

 

update.asp : 更新出題老師審核表單傳來的資料

<% ' 權限認證
' 先把答案都設為答錯
' 再把表單傳來的資料筆數數量,作為迴圈的圈數,逐筆取出
' 更新資料庫
' 轉向網頁到主網頁
%>

 

delete.assp : 刪除題目

<%'權限認證
' 選出題號
' 執行sql
' 轉向網頁到主網頁
%>

 

list.ap : 列出某一題答對的學生清單

<html><head><title>排行榜</title></head>
<body>
1期</b>

<table border="2" cellspacing="1">
<tr>
    <td>對  象:</td>
    <td>年級 </td>
<tr>
    <td>題  目:</td>
    <td>老師出的題目 </td>
</tr>
<tr>
    <td>正確答案:</font></td>
    <td>正確的答案 </td>
</tr>
</table>
<table border="1" cellpadding="2" cellspacing="1">
<tr>
    <td>學號</td>
    <td>班級</td>
    <td>姓名</td>
    <td>答案</td>
</tr>
<%
      
’ 選出題目資料表中,這題答對的同學,照年班級排序
      
’ 如果資料錄不是空的,取出資料錄的資料
%>

<tr>
    <td >印出學生學號 </td>
    <td >印出班級 </td>
    <td >印出姓名 </td>
    <td >印出答案 </td>
</tr>
</table>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p>
</center></div>
<center><font size="5" color="#FF0000">得獎名單正在審核中,目前還無法公佈!</font></center>
</body></html>

 

sort.asp : 列出所有答對的學生的總排行榜

<html><head><title>排行榜</title></head>
<body>

<table border="1" cellpadding="2" cellspacing="1">
<tr>
    <td>學號</td>
    <td>班級</td>
    <td>姓名</td>
    <td>答對次數</td>
</tr>

<tr>
    <td>資料庫裡的學號 </td>
    <td>資料庫裡的班級 </td>
    <td>資料庫裡的姓名 </td>
    <td>資料庫裡的答對次數 </td>
</tr>
</table>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p>
</center></body> </html>

 

4.所謂〝權限認證〞

除了主網頁和排行榜外,都要在程式中放入權限認證。以免玩家級的使用者在瀏覽器的網址列直接輸入值帶入程式。以下是需要設計權限認證的幾個動作:

    只有學生權限才能回答問題。
    只有管理老師可以新增、編修和刪除題目。
    只有管理老師能審核答案。
    只有管理老師能執行存檔。
    只有透過表單傳來的值才寫入資料庫   

我們可以在主程式建構完成後,再加入認證功能。

    另外還要再撰寫程式時注意,所有從表單傳來的值,程式收到後都要過濾傳入值,以避免有心人作SQL資料隱碼攻擊。

5.權限認證部分

    學生和老師登入的帳號密碼檢查表單,我們可以利用石牌國小李忠憲老師提供的程式,作為現成的校務行政帳號做認證機制。下載校務行政系統2.2jsmis.zip 725K[2003/4/11]下載完畢後解開,依照說明拷貝到 x:\inetpub\wwwroot 中。並依照以下步驟修改:

1.global.asa 內容請先修改好:

<SCRIPT LANGUAGE=VBScript RUNAT=Server>

Sub Application_OnStart
    '以下此行設定資料庫來源 請改為正確路徑
Application("ysps1") = "Driver={SQL Server};Server=ysps1;database=JSDB;uid=xxxxx;pwd=xxxxxx"
Application("spps") = "Driver={SQL Server};Server=ysps1;database=spps;uid=xxxxx;pwd=xxxxxx"
Application("board") = "Driver=driver={Microsoft Access Driver (*.mdb)};dbq=d:\inetpub\wwwroot\board\board.mdb;PWD=xxxxxxxx"   '站台上有mdb檔也可以放入Application 變數中
END SUB
</SCRIPT>

2.不喜歡登入畫面的話也可以自己動手製作 check.asp 表單。

 

check.asp程式碼說明

<%
if session("passed")=1 then
    session("topage")=request("topage")
    response.redirect session("topage")
else
    session("topage")=request("topage")
%>
<html><head><title>登入</title></head>
<body>
<form name="idpass" method="POST" action="/check2.asp">
<input type="hidden" name="topage" value="<%=session("topage")%>">
<input type="hidden" name="act" value>
<div align="center">
<center>
<table>
<tr><td width="600">
<table cellspacing="0" cellpadding="2" width="423" border="0" style="border-collapse: collapse" bordercolor="#111111">
<tr><th align="right" width="256">帳號(或學生名牌號碼) </th>
<td width="160"><font color="#FFFFFF"><b>
<input type="text" name="usrid" size="13"></b><b> </b>
</td></tr><tr>
<th align="right" width="256">密碼(或學生身分證號) </th>
<td width="160"><font color="#FFFFFF"><b>
<input type="password" name="pass" size="13"></b><b>
</b></td></tr></table></td></tr></table></center>
</div>
<p align="center">【<a href="Javascript:checkempty(document.idpass)"><b>登入主機</b></a><b>】</b> <b>【</b><a href="Javascript:document.idpass.reset()"><b>清除重填</b></a><b>】</b></p>
</form>
</body></html>
<% end if %>

check2.asp的程式碼說明

<!--#include file="jsmis/public.asp"-->
<%
m_year=request("year")
m_month=request("month")
m_day=request("day")
m_class=request("class")
syear = year(now())-1911
smonth = month(now())
if smonth>8 then
    seme = 1
elseif smonth <2 then
    seme = 1
    syear = syear-1
else
    seme = 2
    syear = syear-1
end if

Set Conn1 = Server.CreateObject("ADODB.Connection")
conn1.open Application("spps1")
usrid=Ucase(request.form("usrid"))
usrid=replace(usrid,"'","")
usrid=replace(usrid,"*","")
usrid=replace(usrid,"%","")
usrid=replace(usrid,"/","")
usrid=replace(usrid,"=","")
usrid=left(usrid,5)

inputpass=Ucase(request.form("pass"))
inputpass=replace(inputpass,"'","")
inputpass=replace(inputpass,"*","")
inputpass=replace(inputpass,"%","")
inputpass=replace(inputpass,"/","")
inputpass=replace(inputpass,"=","")
inputpass=left(inputpass,12)

found=0
if found=0 then    
' 比對帳號,一般老師用
tea_pass=inputpass
tea_id=usrid
sqlstring="select * from SEMP where EMPNO='" & tea_id & "' and PWD='" & ucase(gTransPWD(tea_pass)) & "'"
    Set RS = Conn1.Execute(sqlstring)
    if not RS.eof then found=2  
        '身分是老師,比對帳號成功
    end if
end if
'---------比對身分是學生帳號開始---------
if found=0 then
'身分是學生家長或學生帳號
sqlstring="select *,BSTD_SEME.CLASSNO,BSTD_SEME.SEAT from BSTD,BSTD_SEME where BSTD.STDNO = BSTD_SEME.STDNO and BSTD.IDNO='" & inputpass & "' and BSTD_SEME.CLASSNO='" & left(usrid,3) & "' and BSTD_SEME.SEAT='" & right(usrid,2) & "' and BSTD_SEME.SYEAR=" & syear & " and BSTD_SEME.SEME=" & seme
Set RS = Conn1.Execute(sqlstring)
        if not RS.BOF then
            sid = RS("CLASSNO") & RS("SEAT")
            usrid = right(usrid,5)
            found=3
        end if       
 '身分是學生
end if

end if
    session("topage") = "/msg.asp?msg=歡迎登入!"
    if request("topage") <> "" then session("topage") = Request("topage")
    select case found
    case 0
        response.redirect "/msg.asp?msg=身份確認失敗!<br>無法進入"
    case 1
        '系統保留未來用途,不做事
    case 2
        session("glEmpname") & "'"
        strseme & "' and TEA_NO ='" & session("glEmpid") & "'"
        ' ---老師認證通過後session處理
            session("glPS")=inputpass
            session("glEmpname")=trim(RS("NAME"))
            sqlclass="select CLASSNO from BCLASS where SYEAR= '" & syear & "' and SEME='" & seme & "' and TEA_NO = '" & Ucase(usrid) & "' "
            set RS2=conn1.Execute(sqlclass)
            if not RS2.EOF then session("glClass")=RS2(0)
                    session("glEmpid")=usrid
                    session("glEmail")=Lcase(usrid) & "@webmail.ysps.tp.edu.tw"
                    session("glPS")=RS("PWD")
                    session("glEmpname")=trim(RS("NAME"))
                    session("passed")=3
            end if
' ---學生認證通過後session處理
     case 3
        session("stuid")=usrid
        session("glEmpid")=RS("STDNO")
        session("glPS")=inputpass
        session("glEmpname")=trim(RS("NAME"))
        session("glDepid")=RS("CLASSNO")
        session("glClass")=session("glDepid")
        session("glSeat")=RS("SEAT")
        session("glEmail")="cc" & usrid & "@stu.ysps.tp.edu.tw"
        session("passed")=4
end select
RS.Close
Conn1.close
response.write "<script>"
response.write "location='" & session("topage") & "';"
response.write "</script>"
%>

 

6.填入ASP程式碼 (範例:網路有獎徵答

default.asp (有獎徵答首頁)

<%
Set Conn = Server.CreateObject("ADODB.Connection")
' 直接叫用寫在global.asa 裡的 Application變數
conn.open Application("spps")
' 把sql命令語法指定給sql變數:選擇award_question資料表,並按照結束日期欄位照降冪排序
sql = "select * from award_question order by end_date desc"   
' 執行sql字串並將結果放入資料錄
set rs=conn.execute(sql)
%>

<html><head><title>有獎徵答</title></head>
<body>
<table id="AutoNumber1">
<tr>
    <td><h1>《網路有獎徵答》</h1></td>
    <a href="manager.asp"></a></td>
</tr>
<tr>
    <td><font size="3" color="#385B96">§ <a href="sort.asp">得獎排行榜</a></td>
    <td><a href="manager.asp">管理</a>
    </td>
</tr>
</table><center>
<table border="1">
<tr><td>期別</td><td>對象</td><td>題目</td><td>活動期限</td></tr>
<%
' 如果資料錄是空的
if rs.eof then response.write "<tr><td align=center>目前沒有徵答活動</td></tr>"
' 如果資料錄不是空的[有出過題]
    while not rs.eof
        id = rs("id")           
' 把資料錄中的id欄位的值指定給變數id
        grade = rs("grade") 
' 把資料錄中的grade欄位的值指定給變數grade
        if grade=0 then desc="低年級"   
' 判斷grade變數的值如果=0,指定desc變數=低年級
        if grade=1 then desc="中年級"   
' 判斷grade變數的值如果=1,指定desc變數=中年級
        if grade=2 then desc="高年級"   
' 判斷grade變數的值如果=2,指定desc變數=高年級
        if grade=3 then desc="全校"     
' 判斷grade變數的值如果=3,指定desc變數=全校
        quiz = rs("question")               
' 把資料錄中的question欄位的值指定給變數quiz
        quiz = replace(quiz,chr(13),"<br>")
' 用<br>字串替換掉換行字元
            sdate = rs("start_date")       
' 把資料錄中的start_date欄位的值指定給變數sdate
            edate = rs("end_date")       
 ' 把資料錄中的edn_date欄位的值指定給變數edate
            pdate = rs("post_date")       
' 把資料錄中的post_date欄位的值指定給變數pdate
            if sdate<=date() and edate>=date() then
' 如果今天還可以作答(介於開始日期和結束日期之間)
                bgc = "#eeeeFF"           
' 把這列的背景色變數指定為#eeeeff
            elseif edate<=date()then     
' 如果超過了截止日期 
                bgc = "#aaaacc"            
' 把這列的背景色變數指定為#aaaacc
            else                                  
                bgc = "#cceecc"
             ' 剩下就是尚未到期的題目
            end if
%>

<tr>                           
<% ' 以下分別放入背景色、題號id、適用年級、題目、截止日期 %>
    <td bgcolor="<% =bgc %>"><% = id %> </td>
    <td bgcolor="<% =bgc %>"><% =desc %> </td>
    <td bgcolor="<% =bgc %>"><% =quiz %> </td>
    <td bgcolor="<% =bgc %>"><% = year(edate)-1911 & "/" & month(edate) & "/" & day(edate) %></td>
    <td bgcolor="<% =bgc %>">


    <%
' 判斷日期介於開始和結束之間,也就是還沒過期的話,放上〝我要答〞的超連結

    if sdate<=date() and edate>=date() then %>
        <a href="answer.asp?id=<%=id%>">我要答</a>
    <%
' 判斷如果已經過期的話放上〝得獎名單〞的超連結
     elseif edate < date() then %>

        <a href="list.asp?id=<%=id%>">得獎名單</a>
    <%
' 判斷日期尚未開始,就放上〝敬請期待〞的文字
      elseif sdate > date() then%>

        尚未開始<br>敬請期待
    <% end if %>
</td>
</tr>
<% 
' 移到下一筆資料錄的迴圈底部
    rs.movenext
    wend
%>

</table></center></div></body></html>

manager.asp:老師的管理頁面

<% ' 權限認證部分等完成後後再補 %>

<html><head><title>有獎徵答</title></head>
<body>
<h1 align="center">管理選項</h1>
<div align="center"><a href="default.asp">回有獎徵答首頁</a>

<table border="1">
<tr><td>期別</td><td>對象</td><td>題目(點題目審閱)</td><td>作答人數</td><td><a href="addnew.asp">新增題目</a></td></tr>
<%
Set Conn = Server.CreateObject("ADODB.Connection")
conn.open Application("spps")
sql = "select * from award_question order by id desc"   
’ 依照id來排序
set rs=conn.execute(sql)                                        
 ’ 執行sql指令放入資料錄rs
while not rs.EOF                                                   
’ 如果資料錄不是空的
    id = rs("id")
    grade = rs("grade")
    if grade=0 then desc="低年級"
    if grade=1 then desc="中年級"
    if grade=2 then desc="高年級"
    quiz = rs("question")
    quiz = replace(quiz,chr(13),"<br>")
    total = rs("num")                                              
’ 統計回答人數
    %>

    <tr>
        <td><% =id %> </td>
        <td><% =desc %> </td>
<% ' 點題目老師可以去審核答案的超連結 %>
        <td><a href=checkit.asp?id=<% =id %>><% =quiz %></a> </td>
        <td><% =total %> </td>
        <td>
<% ' 老師的管理選項 %>
        <a href=edit.asp?id=<% =id %>>修改</a> 
        <a href=delete.asp?id=<% =id %>>刪除</a><br>
        <a href=list.asp?id=<% =id %>>得獎名單</a>
    </td>
    </tr>
<%
    rs.movenext
    wend
%>

</table>
<a href="default.asp">回有獎徵答首頁</a>
</center></div></body></html>

addnew.asp :新增題目

<% ' 權限認證部分後補 %>

<% ' 取現在的年、月、日指定給變數,以便後面的比對
    thisyear = year(now())-1911
    thismonth = month(now())
    thisday = day(now())

    Set Conn = Server.CreateObject("ADODB.Connection")
    conn.open Application("spps")
    sql = "select max(id) from award_question"       
' 選出目前題號最大的值
    set rs=conn.execute(sql)
        if isnull(rs(0)) then                                     
' 如果資料錄裡是空的 
            id=1               
        else                                                        
' 已經有題號,就把題號加一
            id = rs(0) + 1
        end if
%>

<html><head><title>新增題目</title></head>
<body><h1 align="center"><font face="標楷體">新增題目</h1>
<hr>
<% =id %>期有獎徵答                                '目前題號
<form method="POST" action="save.asp">
<input type=hidden name=id value="<% =id %>">
<table border="2" cellspacing="1">
<tr><td >適用階段</td>
<td >
    <select size="1" name="grade">
        <option value="0">低年級</option>
        <option value="1">中年級</option>
        <option value="2">高年級</option>
        <option value="3">全校</option>
    </select>
</td></tr>
<tr>
<td >題目是</td>
        <td><textarea rows="5" name="quiz" cols="33"></textarea> </td>
</tr>
<tr><td>正確答案</td><td ><input type="text" name="correct" size="35"></td></tr>
<tr><td >開始日期</td><td >
        <select size="1" name="syear">
            <% for i=thisyear to thisyear+1      ' 迴圈範圍只要今年和明年就可以了 %>
                    <option value="<% =i %>"><% =i %></option>
            <% next %>
        </select>年

        <select size="1" name="smonth">
            <% for i=1 to 12%>
                    <option <% if i=thismonth then  ' 如果剛好是這個月 %>selected<% end if %> value="<% =i %>"><% =i %></option>
            <% next %>

        </select>月

        <select size="1" name="sday">
            <% for i=1 to 31%>
            <option <% if i=thisday then   ' 如果剛好是今天 %>selected<% end if %> value="<% =i %>"><% =i %></option>
            <% next %>
        </select>日
</td></tr>
<tr><td >結束日期</td>

<td ><select size="1" name="eyear">
        <% for i=thisyear to thisyear+1%>
            <option value="<% =i %>"><% =i %></option>
        <% next %>
        </select>年

        <select size="1" name="emonth">

        <% for i=1 to 12%>
            <option <% if i=thismonth then %>selected<% end if %> value="<% =i %>"><% =i     %></option>
        <% next %>
        </select>月

        <select size="1" name="eday">
        <% for i=1 to 31%>
            <option <% if i=thisday then %>selected<% end if %> value="<% =i %>"><% =i %></option>
        <% next %>
        </select>日
</td></tr>
<tr>
<td >公告日期</td>
<td >
    <select size="1" name="pyear">
        <% for i=thisyear to thisyear+1%>
            <option value="<% =i %>"><% =i %></option>
        <% next %>
    </select>年

    <select size="1" name="pmonth">
    <% for i=1 to 12%>
        <option <% if i=thismonth then %>selected<% end if %> value="<% =i %>"><% =i     %></option>
    <% next %>
    </select>月

    <select size="1" name="pday">
        <% for i=1 to 31%>
            <option <% if i=thisday then %>selected<% end if %> value="<% =i %>"><% =i %></option>
        <% next %>
</select>日
</td> </tr> </table> </center>

<p align="center">
<input type="submit" value="存檔" name="B1"> <input type="reset" value="重寫" name="B2"></p>
</form>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p></body> </html>

save.asp : 各種動作的存檔程式

<%   ' 權限判斷不可忘記補上
if session("glempid")="WINER" then permtype="A"
if permtype<>"A" then response.redirect "../msg.asp?msg=您無權使用此程式"
    Set Conn = Server.CreateObject("ADODB.Connection")
    conn.open Application("spps")
  ' 去除使用者輸入的表單傳來的資料中,潛藏有SQL隱碼攻擊可能的單引號字串
        id=Request("id")
        id=replace(id,"'","")
        grade=Request("grade")
        quiz=Request("quiz")
        quiz=replace(quiz,"'","〝")
        correct=Request("correct")
        correct=replace(correct,"'","〝")
  ' 因為標單上選的是國曆年,寫入資料庫的是民國西元要經過轉換、再把年月日連接起來,定給給變數
        sdate = Request("syear")+1911 & "/" & Request("smonth") & "/" & Request("sday")
        sdate=replace(sdate,"'","")
        edate = Request("eyear")+1911 & "/" & Request("emonth") & "/" & Request("eday")
        edate=replace(edate,"'","")
        pdate = Request("pyear")+1911 & "/" & Request("pmonth") & "/" & Request("pday")
        pdate=replace(pdate,"'","")
  ' 選出標單傳來的題號的SQL語法
    sql = "select * from award_question where id=" & id
    set rs=conn.execute(sql)
  ' 如果資資料錄是空的(沒有這個id,表示資料庫中沒有這個題目,動作一定是新增)
        if rs.eof then

  ' 就把後面要執行的sql字串變數,寫成插入新的id、年級、題目、答案、日期等資料到資料表award_question中
            sql = "Insert into award_question (id,grade,question,correct,start_date,end_date,post_date) values ("
sql = sql & id & "," & grade & ",'" & quiz & "','" & correct & "','" & sdate & "','" & edate & "','" & pdate & "')"
        else
  ' 否則就寫成更新資料到資料表award_question中
            sql = "Update award_question set grade=" & grade & ",question='" & quiz & "',correct='" & correct & "',start_date='"
            sql = sql & sdate & "',end_date='" & edate & "',post_date='" & pdate & "' where id=" & id
        end if
  ' 執行sql命令
    conn.execute(sql)

  ' 把網頁轉到〝管理頁面〞
response.redirect "manager.asp"
%>

answer.asp 學生填答的表單

<%  ' 權限判斷
if session("passed")=0 then response.redirect "/check.asp?pageto=/award/answer.asp"
if session("passed")<>4 then response.redirect "/msg.asp?msg=很抱歉,只有學生可以參加有獎徵答活動!"

Set Conn = Server.CreateObject("ADODB.Connection")
conn.open Application("spps")
 
' 取出表單傳來的id
        id = Request("id")
        id = replace(id,"'","")
    sql = "select * from award_question where id=" & id
        set rs=conn.execute(sql)
        grade = rs("grade")
        quiz = rs("question")
        edate = rs("end_date")
            if grade < 3 then       
' 判斷題目中限定不是全校年段的話
                if int((cint(left(session("glClass"),1))-1)/2) <> grade then
                
' 取回經過check2.asp檢查後,產生的 glClass session變數。左邊算起取一位,減去1、取整數後,再除以2就可以判斷學生帳號中的年級是低、中、或是高年級
                    response.redirect "/msg.asp?msg=很抱歉,您不能回答這個題目!"
                    
' 年段不合的話
                end if
            end if
sql = "select * from award_answer where id=" & id & " and stdno='" & session("glEmpid") & "'"             
'根據學生的學號 session,選出這個學生有回答過這題的紀錄
set rs1 = conn.execute(sql)
%>

<html><head><title>我要回答</title></head>
<body>
<h1>我會回答問題</h1>
<hr>
<% my_name = session("stuid") & session("glempname") %>     ' 把名牌號碼和姓名接起來
<p><font color="blue"><% =my_name %>小朋友請注意以下規則:</p>
        1.每人只能回答一次,無法反悔改答案<br>
        2.請多利用圖書館或網路尋找答案<br>
        3.請不要替他人作答或洩漏答案,影響比賽的公平性<br>
        4.所有的成績會在期末統計,並頒發獎品給答對最多題目的同學<br>
        5.現有獎品:李忠憲老師提供 PS2 五台 , XBOX 三台 <br>
<% if not rs1.EOF then      ' 資料錄裡已經有學生回答過的資料了    %>
        <marquee behavior="alternate">你已經答過這題了,不可以修改或再次作答!          
        </marquee><a href="default.asp">回有獎徵答首頁</a></p>
<% else %>
        本期題目:<% =quiz %><br>
        我的答案是:
            <form method="POST" action="thanx.asp">
            <input type="hidden" name="id" value="<% =id %>">
            <textarea rows="5" name="answer" cols="45" >
                我是<% =name %>,我的答案是:
            </textarea>
    <input type="submit" value="寫好了,幫我儲存" name="B1"> <input type="reset" value="重寫" name="B2"></form>
<% end if %>
</body></html>

thankx.asp:寫入資料庫並寄發eamil 通知管理老師

<%'權限認證部分候補 %>
<%
Set Conn = Server.CreateObject("ADODB.Connection")
conn.open Application("spps")
        id = request("id")
        id = replace(id,"'","")
        sql = "select * from award_question where id=" & id
    set rs=conn.execute(sql)
        quiz = rs("question")
        edate = rs("end_date")
        pdate = rs("post_date")
        count=rs("num")+1       
             ' 回答過的計數器欄位+1
        answer = Request("answer")
        answer = replace(answer,"'","")
     ' 判斷資料表中有沒有題號和學生學號的sql
    sql = "select * from award_answer where stdno='" & session("glEmpid") & "' and id=" & id
    Set rs1=conn.execute(sql)
        if rs1.EOF then       
' 如果資料標裡面沒有紀錄
          
 'sql 語句就寫成新增一筆
            sql = "Insert into award_answer (id,stdno,classno,student,answer) values (" & id & ",'" & session("glEmpid") & "','" & session("glClass") & "','" & session("glEmpname") & "','" & answer & "')"
            conn.execute(sql)       
     ' 執行新增sql
            sql = "Update award_question set num=num+1 where id=" & id
            conn.execute(sql)           
   ' 執行修改已回答的人數sql
        end if

' 自動寄發email給管理老師段落
    name = session("glempname")
    email = "cc" & session("stuid") & "@stu.xxps.tp.edu.tw"
    ' 連接成學生的email
    Subject = "網站有獎徵答有同學填答了!"
    Words =answer
    Body="<html><head><meta http-equiv='Content-Type' content='text/html; charset=big5'></head><body><table border=0 bgcolor=#dfefff style=font-size:11pt width=550><tr><td bgcolor=#6699cc><font color= white><b> ■答題學生姓名:" & Name & "</b></td>" & chr(13) 
                ' chr(13)是換行字元 
    Body=Body & "<tr><td align=center ><font color=darkblue face=標楷體><h2>有獎徵答學生填答通知</h2>" & "</td></tr>" & chr(13)
    Body=Body & "<tr><td>■學生email:" & email & chr(13)
    Body=Body & "</td></tr>"
    Body=Body & "<tr><td>【題目=" & id & quiz & "】)</td>" & chr(13) & "學生的答案:" & words & chr(13)
    Body=Body & "<tr><td><a href = 'http://www.xxps.tp.edu.tw/checkt.asp?topage=/award/manager.asp'>○請出題老師在活動截止前點這裡前往審核○</a></td></tr>" & chr(13)
    Body=Body & "<tr><td align=right><font color= red >寄發時間:" & now()
    Body=Body & "</tr></table>" & chr(13)

        Set Mail=Server.CreateObject("CDONTS.NewMail")
        Mail.MailFormat=0
        Mail.BodyFormat=0
        Mail.From = "
ysps@mail.ysps.tp.edu.tw"
        Mail.to = "
teacher@xxpx.tp.edu.tw;" & email
        Mail.Subject = subject
        Mail.Body = Body
        Mail.Send
        Set Mail=Nothing
' -------自動寄發email 結束 %>

<html><head><title>謝謝您的作答</title></head>
<body>
<h1 align="center">謝謝您參加xx國小有獎徵答作答</h1>
<hr>
<p align="center"><b><font color="#385B96">您的答案已經存入資料庫,請等待截止日期老師審查 ,於<% =edate %>後才會公佈正確答案及得獎名單!並於期末頒獎</b></p>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p>
</body></html>

edit.asp : 出題老師編修題目用 ,和addnew.asp很像,可以複製addnew.asp來修改

<%
if session("glempid")="WINER"  then permtype="A"
if permtype<>"A" then response.redirect "../msg.asp?msg=您無權使用此程式"
    thisyear = year(now())-1911
    thismonth = month(now())
    thisday = day(now())
    id = request("id")

Set Conn = Server.CreateObject("ADODB.Connection")
conn.open Application("spps")

    sql = "select * from award_question where id=" & id
        set rs=conn.execute(sql)
        grade = rs("grade")
        quiz = rs("question")
        correct = rs("correct")
        sdate = rs("start_date")
        syear = year(sdate)

        smonth = month(sdate)
        sday = day(sdate)
        edate = rs("end_date")
        eyear = year(edate)
        emonth = month(edate)
        eday = day(edate)
        pdate = rs("post_date")
        pyear = year(pdate)
        pmonth = month(pdate)
        pday = day(pdate)
%>
<html><head><title>編修題目</title></head>
<body>
<h1 align="center"><font face="標楷體">新增題目</font></h1><hr>
<% =id %>期有獎徵答

<form method="POST" action="save.asp">
<input type=hidden name=id value="<% =id %>">
<div align="center"><center>
<table border="2" cellspacing="1">
<tr>
<td>適用年段</td>
<td>
<select size="1" name="grade">
    <option value="0" <% if grade=0 then %>selected<% end if %>>低年級</option>
    <option value="1" <% if grade=1 then %>selected<% end if %>>中年級</option>
    <option value="2" <% if grade=2 then %>selected<% end if %>>高年級</option>
    <option value="3" <% if grade=3 then %>selected<% end if %>>全校</option>
</select>
</td></tr>
<tr>
<td>題目是</td>
    <textarea rows="5" name="quiz" cols="33"><% =quiz %></textarea>
</td>
</tr>
<tr>
    <td>正確答案</td>
    <td >
    <input type="text" name="correct" size="35" value="<% =correct %>">
</td>
</tr>
<tr>
    <td bgcolor="#33CCFF"><font color="#FFFFFF">開始日期</font></td>
    <td bgcolor="#CCFFFF">
    <select size="1" name="syear">
        <% for i=thisyear to thisyear+1%>
            <option <% if i=syear then %>selected<% end if %> value="<% =i %>"><% =i %></option>
        <% next %>
    </select>年

    <select size="1" name="smonth">
        <% for i=1 to 12%>
        <option <% if i=smonth then %>selected<% end if %> value="<% =i %>"><% =i %></option>
        <% next %>
    </select>月

    <select size="1" name="sday">
        <% for i=1 to 31%>
        <option <% if i=sday then %>selected<% end if %> value="<% =i %>"><% =i %></option>
        <% next %>
    </select>日
</td></tr>
<tr>
        <td bgcolor="#33CCFF"><font color="#FFFFFF">結束日期</font></td>
        <td bgcolor="#CCFFFF">
        <select size="1" name="eyear">
            <% for i=thisyear to thisyear+1%>
            <option <% if i=eyear then %>selected<% end if %> value="<% =i %>"><% =i %></option>
            <% next %>
        </select>年

        <select size="1" name="emonth">
            <% for i=1 to 12%>
            <option <% if i=emonth then %>selected<% end if %> value="<% =i %>"><% =i %></option>
            <% next %>
        </select>月

        <select size="1" name="eday">
            <% for i=1 to 31%>
            <option <% if i=eday then %>selected<% end if %> value="<% =i %>"><% =i %></option>
            <% next %>
        </select>日
</td></tr>
<tr>
    <td bgcolor="#33CCFF"><font color="#FFFFFF">公告日期</font></td>
    <td bgcolor="#CCFFFF">
        <select size="1" name="pyear">
            <% for i=thisyear to thisyear+1%>
            <option <% if i=pyear then %>selected<% end if %> value="<% =i %>"><% =i %></option>
            <% next %>
        </select>年

        <select size="1" name="pmonth">
        <% for i=1 to 12%>
        <option <% if i=pmonth then %>selected<% end if %> value="<% =i %>"><% =i %></option>
        <% next %>
        </select>月

        <select size="1" name="pday">
            <% for i=1 to 31%>
            <option <% if i=pday then %>selected<% end if %> value="<% =i %>"><% =i %></option>
            <% next %>
        </select>日
</td></tr>
</table></center></div>
<p align="center">
<input type="submit" value="存檔" name="B1">    <input type="reset" value="重寫" name="B2"></p>
</p></form>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p>
</body></html>

checkit.asp:老師審查答案用

<% if session("glempid")="WINER" then permtype="A"
if permtype<>"A" then response.redirect "/msg.asp?msg=您無權使用此程式"
%>
<html><head><title>審閱答案</title></head>
<body>
<h1 align="center"><font face="標楷體">審閱答案</h1><hr>
<%
    id = Request("id")
    id = replace(id,"'","")
    Set Conn = Server.CreateObject("ADODB.Connection")
    conn.open Application("spps")
        sql = "select * from award_question where id=" & id
        set rs1=conn.execute(sql)
        grade = rs1("grade")
        if grade=0 then desc="低年級"
        if grade=1 then desc="中年級"
        if grade=2 then desc="高年級"
        quiz = rs1("question")
        correct = rs1("correct")
       
' 選出所有學生已回答的答案sql
        sql = "select * from award_answer where id=" & id & " order by classno"
        set rs=conn.execute(sql)
%>
<table border="2" cellspacing="1">
<tr>
    <td>對  象:</td><td><% =desc %> </td>
<tr>
    <td>題  目:</td><td><% =quiz %> </td>
</tr>
<tr>
    <td>正確答案:</td><td><% =correct %> </td>
</tr>
</table>
<table border="2" cellspacing="1">
<tr>
    <td >學號</td><td >班級</td><td >姓名</td><td >答案</td><td >答對</td>
</tr>
<form method="POST" action="update.asp">
<input type="hidden" name="id" value="<% =id %>">
<%
while not rs.EOF   
' 如果有資料的話
    stdno = rs("stdno")
    classno = rs("classno")
    stdname = rs("student")
    answer = rs("answer")
    correct = rs("correct")
%>
<tr>
<td><% =stdno %> </td>
<td><% =classno %> </td>
<td><% =stdname %> </td>
<td><% =answer %> </td>
<td><% ' 如果原先審核過答案的話,答對的CheckBox要打勾%>
    <input type="checkbox" name="<% = "a" & stdno %>" value="ON" <% if correct then %>checked<% end if %>>
</td>
</tr>
<%
    rs.movenext
    wend
%>
</table></center>
<p align="center"><input type="submit" value="審核完畢,請幫我儲存" name="B1">

<input type="reset" value="重新審核" name="B2"></p></form></body></html>

update.asp : 更新出題老師審核表單傳來的資料

<%
if session("glempid")="WINER"  then permtype="A"
if permtype<>"A" then response.redirect "../msg.asp?msg=您無權使用此程式"

Set Conn = Server.CreateObject("ADODB.Connection")
conn.open Application("spps")

    id = Request("id")
    id = replace(id,"'","")
' 先把答案都設為答錯
    sql = "Update award_answer set correct=0 where id=" & id
    conn.execute(sql)
' 用for each .. in......next   以表單傳來的資料筆數數量,作為迴圈的圈數,逐筆取出
    for each x in Request.Form   
        answer = Request(x)   
’ 取回答案(因為判斷是否被老師勾選了)
        stdno = mid(x,2)       
 ’ 學生學號
        if answer="ON" then    ' 如果被勾選答對
        sql = "Update award_answer set correct=1 where id=" & id & " and stdno='" & stdno & "'"
        conn.execute(sql)
        end if
    next
response.redirect "manager.asp"
%>

delete.assp : 刪除題目

<%
if session("glempid")="WINER"  then permtype="A"
if permtype<>"A" then response.redirect "../msg.asp?msg=您無權使用此程式"

    id = Request("id")
    id = replace(id,"'","")

    Set Conn = Server.CreateObject("ADODB.Connection")
    conn.open Application("spps")
        sql = "Delete from award_question where id=" & id
    conn.execute(sql)
        sql = "Delete from award_answer where id=" & id
    conn.execute(sql)
response.redirect "manager.asp"
%>

list.ap : 列出某一題答對的學生的排行榜

<%
Set Conn = Server.CreateObject("ADODB.Connection")
conn.open Application("spps")
    id = Request("id")
    id = replace(id,"'","")
    if id="" then
        sql = "select max(id) from award_question where post_date < getdate()"
        ' SQL中要用getdate()函數來取日期,不可以用now() 函數
        set rs=conn.execute(sql)
            if not rs.eof then id = rs(0)
    end if
%>

<html><head><title>得獎名單</title></head>
<body><h1 align="center"><font face="標楷體" color="#000080">得獎名單</font></h1><hr>
<% if id<>"" then        ’ 有題號的話
    sql = "select * from award_question where id=" & id       
’ 從資料表裡找到這題
    set rs1=conn.execute(sql)       
    grade = rs1("grade")
        if grade=0 then desc="低年級"
        if grade=1 then desc="中年級"
        if grade=2 then desc="高年級"
    quiz = rs1("question")
    correct = rs1("correct")
%>
<% =id %>期</b>

<table border="2" cellspacing="1">
<tr>
    <td>對  象:</td>
    <td><% =desc %> </td>
<tr>
    <td>題  目:</td>
    <td><% =quiz %> </td>
</tr>
<tr>
    <td>正確答案:</font></td>
    <td><% =correct %> </td>
</tr>
</table>
<table border="1" cellpadding="2" cellspacing="1">
<tr>
    <td>學號</td>
    <td>班級</td>
    <td>姓名</td>
    <td>答案</td>
</tr>
<%       ’ 選出題目資料表中,這題答對的同學,照年班級排序
sql = "select * from award_answer where id=" & id & " and correct=1 order by classno"
set rs2=conn.execute(sql)

while not rs2.EOF        ’ 如果資料錄不是空的
    stdno = rs2("stdno")
    classno = rs2("classno")
    stdname = rs2("student")
    answer = rs2("answer")
%>

<tr>
    <td ><% =stdno %> </td>
    <td ><% =classno %> </td>
    <td ><% =stdname %> </td>
    <td ><% =answer %> </td>
</tr>
<%
    rs2.movenext
    wend
%>
</table>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p>
</center></div>
<% else %>
<center><font size="5" color="#FF0000">得獎名單正在審核中,目前還無法公佈!</font></center>
<% end if %>
</body></html>

sort.asp : 列出所有答對的學生的總排行榜

<%
Set Conn = Server.CreateObject("ADODB.Connection")
conn.open Application("spps")

    sql = "select stdno,classno,student,count(correct) as total from award_answer where correct=1 group by stdno,classno,student order by total desc,classno"
    Set rs2=conn.execute(sql)
%>
<html><head><title>排行榜</title></head>
<body>

<table border="1" cellpadding="2" cellspacing="1">
<tr>
    <td>學號</td>
    <td>班級</td>
    <td>姓名</td>
    <td>答對次數</td>
</tr>
<%
while not rs2.EOF
    stdno = rs2("stdno")
    classno = rs2("classno")
    stdname = rs2("student")
    total = rs2("total")
%>
<tr>
    <td><% =stdno %> </td>
    <td><% =classno %> </td>
    <td><% =stdname %> </td>
    <td><% =total %> </td>
</tr>
<%
    rs2.movenext
    wend
%>

</table>
<p align="center"><a href="default.asp">回有獎徵答首頁</a></p>
</center></body> </html>

 

八、測試程式和偵錯

    良好的程式測試程序和偵錯,是需要至少一位專業的測試員來做的專職工作,他需要看得懂 html 標籤語法、具備基礎的ASP程式撰寫能力、還要有系統管理能力、HTTP協定 Server / Client 工作原理的熟悉、和多方試探的好奇心、及超人一等的耐性及偵錯敏感度。

去哪裡找這種人?

    一個好的程式設計師一定是個好測試員。找不到幫手,就自己動手吧!

  1. 測試程式時我們最好開啟IIS中的內容→應用程式名稱→設定:

    〝啟用ASP用戶端指令偵錯〞和〝將詳細的ASP錯誤訊息傳送給用戶端〞選項勾選。

  2. 對於SQL語法錯誤的部分,我們可印出SQL字串來判斷。例如:
    ..........略..........
    sql = "select stdno,classno,student,count(correct) as total from award_answer where correct=1 group by stdno,classno,student order by total desc,classno"
    response.wriet sql
    response.end

    Set rs2=conn.execute(sql)
    .........略...........

  3. 如果是程式運算中的變數值有錯,我們可以秀出來檢查。例如:
    <script>alert('<%=stdname%>')</script>

  4. 需要模擬學生的帳號權限,我們可以〝小心地〞考慮使用一組萬用密碼作為開發程式測試用。
    實做上,可以修改 check2.asp 內容讓程式判斷密碼只要是特定字串,檢查就算通過。例如:

    .....略.......
        if inputpass="54_Student" then pwd_passed = 1
         .........
        end if

    .....略.......

  5. 使用萬用密碼時要特別注意:
    選用文數字混用的無規則可循的密碼,不容易被猜到
    此事需嚴格保密
    使用後要清除IE的密碼記憶功能
    限制網芳讀取該資料夾的權限

  6. 從網路抓回來了 ASP 程式,解壓縮開,拷貝放到自己網站上後,發現網頁出現類似〝資料庫必須使用更新查詢....〞等錯誤訊息畫面,這多半是 MDB 檔寫入權限設定的問題。因為 WINDOWS NT/2000 的 IIS 伺服器它的執行的身分是:IUSER_你的主機名稱。ASP 程式要將資料寫入資料庫也是使用這個使用者身分,因此 MDB 資料庫檔要記得給這個使用者能讀取和寫入的權限。使用 SQL Server 作為後端資料庫,則可以避免這類錯誤。

     舉例來說,以學校神通標案的 WEB SEVER 來架站,電腦名稱叫做 WEB,網路上所有來 WEB 這台主機觀賞網頁的瀏覽者,身分都是[IUSER_WEB]。

      因為放在 NTFS 上,所以我們還必須把 wwwroot 資料夾中的檔案和 MDB 資料庫權限, 指定給這個使用者,以下是權限設定:

    物件種類

    權限設定

    資料夾

    改為 [IUSER_你的主機名稱] 可讀取,執行(進入)

    ASP或HTML檔案

    改為 [IUSER_你的主機名稱] 可讀,指令

    MDB檔

    改為 [IUSER_你的主機名稱]可讀取,寫入

    要提供上傳檔案的資料夾[UPLOAD]

    改為 [IUSER_你的主機名稱]可讀取,執行,寫入

  7. 在校內架設 Windows2000 SERVER+ IIS5.0 WEB 伺服器時,要讓校外也能連到,要處理以下事項:

    • 真實網域的 IP 設定,如:163.21.224.4和 NAT 對應設定

    • 在防火牆上設定〝AnyNet-to-你的電腦-http通訊協定-[port80]-Any Time放行〞。 若有開放FTP還要再加一條:〝AnyNet-to-你的電腦-FTP 通訊協定-[port21]-Any Time放行〞。

    • 因為架站要24小時開機,所以應該準備一台UPS,並在[控制台]-[電源選項]-[UPS]中設定好選項,並將UPS服務啟動。

    • 必須在校內、對外的兩台DNS 上主機上登錄名稱,否則您的網站只能使用IP連結,而不能使用Domain Name。


 

、 安裝/修改別人寫的 ASP 程式

  這裡提供的範例程式都經過測試和篩選,算是適合大多數老師入門所需。其中多半是從網路找來。這些不藏私的程式設計師開發的 ASP 程式願意分享給大家,是我們的福氣。範例程式都已用 ZIP 打包,使用下載打包版前請詳細閱讀以下步驟:

  1. 下載回去後,暫時存到桌面,有安裝ZIP解壓縮程式的話,按滑鼠右鍵選擇[解壓縮到.....資料夾],解壓縮所有檔案到桌面的XXX資料夾,要還原壓縮檔原有的目錄結構。

  2. 執行[FrontPage0],點[檔案]-[開啟WEB][輸入你的網址 :例如 http://www.ysps.tp.edu.tw/] 在區網的話可以輸入UNC路徑: \\dd\wwwroot

  3. 輸入您的帳號密碼 。若是您沒有輸入密碼就可以進入,您的網站安全漏洞可就大了。

  4. 等資料夾都列出來後,按[檢視]-[資料夾清單]開啟資料夾清單 。

  5. 按[顯示桌面]先切換到[桌面]-[複製 ]剛才解壓縮好的資料夾,-[貼在資料夾清單]的[根目錄]下,FrontPage會 自動把該資料夾自動上傳到您的網站。

  6. 把要設定的檔案和資料夾權限設定好

  7. 開啟瀏覽器,輸入網址測試單一ASP套件是否成功

  8. 製作網頁來連結這些新網頁的新功能。

  9. 安裝新套件之前,請一定要先詳細閱讀每個套件裡面原作者的說明文件。

  10. 所有套件程式中的MDB資料庫,只要有帳號密碼資料在的 ,一定要放在〝別人不知道和猜不到的位置〞,不然網路上大駭小駭彼彼皆是,萬一重要的資料庫透過網址列被下載抓走,[點這裡試試看抓資料庫],你的網站就完全 落在別人的掌控之中了。

  11. SQL的效能高過MDB甚多,如果想要把MDB檔資料庫轉到SQL Server ,轉換的步驟如下:

  12. 步驟一、確認你的 ASP 程式能以 mdb 方式正常執行。

    步驟二、開啟MSSQL(需以管理員身分登入)開啟SQL的企業管理員(Enterprise Manager)主控台。

    步驟三、新增一個資料庫,例如取名為「YSPS」。

    步驟四、把資料庫MDB檔拷貝到這台SQL Server 上,例如:桌面。

    步驟五、將 此MDB檔匯入資料庫 YSPSWEB。

    步驟六、以文字編輯器開啟你的虛擬目錄下的 global.asa 內容,把開啟資料庫的連結字串變成 Application。

    步驟七、開啟所有套件中的ASP程式裡面,修改開啟資料庫連結的方式和程式碼。

    步驟八、上網測試程式,並修改ASP程式碼到能正常工作。

    步驟九、安排資料庫備份排程,備份資料庫到安全的地方。

以下 ASP 程式您可以在這裡 http://dd.ysps.tp.edu.tw/html/13.asp下載。

ASP範例程式

WEB檔案管理員 範例http://dd.ysps.tp.edu.tw/manager/index.asp

[作者 : 李忠憲] 。相當不錯的照片、檔案下載工具,透過網芳或ftp上傳,只要分類建好目錄,並拖入各個資料夾,此asp程式會利用FSO物件,即時產生線上網頁,如果資料夾含〔背景】兩字,程式會把該圖片自動作成背景圖。

【圖片素材庫】 http://dd.ysps.tp.edu.tw/photo/manager.asp

這是資源豐富的花蓮教網陳立輝先生修改李忠憲老師的檔案管理員,並加入了一大堆新功能,包括搜尋、人氣、排行、留言版、網友上傳[當然需安裝BASP21.exe上傳元件才能使用上傳功能]、好站介紹等。維護上因為要做檔案流水號和縮圖,使用管理稍微複雜,mdb路徑記得要修改[0729更正]  詳請參閱使用說明

學校行事曆系統  http://dd.ysps.tp.edu.tw/calendar/index.htm

[作者 : 萬芳國小]這是大家耳熟能詳的行事曆,也修改了一些小BUG,如果想要把今天的行事放在跑馬燈,嵌入您的首頁的話,請用  [dd改寫],或今日行事速查 [dd改寫],不含帳號認證模組,下載後解開來,放到c:\inetpub\wwwroot\calendar中,把資料庫權限改為IUSER_主機名稱,可讀寫即可,若放到其他資料夾,需修改資料庫路徑,搭配萬芳的權限認證模組[pwd.zip]即可使用。

最新消息公告版[逸仙 用的行政公佈欄]  http://dd.ysps.tp.edu.tw/board/index.asp

[作者 : 萬芳國小]dd修改版] 此版加入意表icon和連結逸仙短語集今日行事跑馬燈,ettoday 等 iframe ,需BASP21.exe 上傳檔案用的模組,下載後解開來,放到c:\inetpub\wwwroot\calendar中,若放到其他資料夾,需修改資料庫路徑,把資料庫權限改為IUSER_主機名稱可讀寫,upload資料夾權限可讀寫、及可執行即可。張貼完成會自動寄發電子郵件[已註解暫停]給全校老師,但因各校要求老師收電子郵件和推動WEB化晨會情況不一,請視情況開放。搭配萬芳的權限認證模組[pwd.zip]即可使用。

動網討論區 [動網 Aspsky.com]  http://dd.ysps.tp.edu.tw/bbs/

作者:動網 Aspsky.com。中國大陸動網開發的超強多人使用的討論區[論壇系統],阿言中文化。

mdb版計數器  http://dd.ysps.tp.edu.tw/counter/counter.asp

作者:奕名。最多人使用的圖形計數器,可紀錄今天、昨天和訪客總數,若放到其他資料夾,需修改資料庫路徑。

研習課程查詢[作者 : 李忠憲]  http://dd.ysps.tp.edu.tw/研習報名/showclass.asp

功能算是完備的研習課程查詢,可自動寄發電子郵件給報名者。至於介面....就...,搭配萬芳的權限認證模組[pwd.zip]即可使用。

線上人數 [含線上飛鴿傳書]  http://dd.ysps.tp.edu.tw/online/onlinemsg.asp

算很有趣的線上人數計數器,可顯示來訪者的ip,不用資料庫,可一對一線上對談,傳書來時,和寄出時都有音效。

隨機撥放背景音樂  http://dd.ysps.tp.edu.tw/music/music.asp

[作者 : 李忠憲]也是用FSO物件讀取目錄內的音樂檔,隨機亂數取一個當背景音樂

逸仙短語集  http://dd.ysps.tp.edu.tw/short/index.asp

這是我們校長的點子,他希望能一進網頁順便看到一些勵志話語,我使用下面這個 每日一笑  改出來的, 新增短語 的功能需加上權限認證[為方便測試已移除張貼權限],若放到其他資料夾,需修改資料庫路徑。

小桶子留言版 [作者 : 小桶子] http://dd.ysps.tp.edu.tw/小桶子留言版/CuteBook.asp

用氣泡顯示方式顯示留言,蠻可愛的留言版。回硬漢管理功能的刪除留言的位置設計的有點怪,不過用過一次就知道了。

每日芝麻事  http://dd.ysps.tp.edu.tw/線上日誌/news.asp

線上新聞或班級的活動紀錄,作為線上日誌也不錯,若放到其他資料夾,需修改資料庫路徑

線上考試系統 題目 http://dd.ysps.tp.edu.tw/線上測驗/enter.asp

線上能算初應試者成績,題目需要用ACCESS開資料庫編是比較麻煩的地方

KM知識管理系統-資料庫(Access)版[作者 : simon] http://dd.ysps.tp.edu.tw/tf/index.asp 

陽春型安安行事曆 http://dd.ysps.tp.edu.tw/安安行事曆/login.asp

陽春型網站評鑑 http://dd.ysps.tp.edu.tw/goodweb/index.asp

水瓶柘榴子檔案總管 http://dd.ysps.tp.edu.tw/doc/fm.asp

簡單方便,純文字,無圖片,能瀏覽開啟檔案,也能上傳的web檔案管理員

win2000線上變更密碼[作者 : 蔡俊彥] http://dd.ysps.tp.edu.tw/win2000線上變更密碼/w2kchpasswd.asp

這是Server管理員用專用,不適合一般老師 說明檔:winchpasswd v1.0 線上更改密碼程式

校園網路IP管理 http://dd.ysps.tp.edu.tw/ip/index.asp

這是逸仙早期的ip管理[C Class等級固定ip],現行的版本加上了各欄位排序功能,和使用者上網次數統計[尚未整理完成]。

笑傲江湖網路社區聊天室1.0[原著:野比俱樂部修改 :正和] http://dd.ysps.tp.edu.tw/笑傲江湖/1index.htm

非常有趣的另類聊天室,就像闖蕩江湖探險般,有武俠風格的MUD多人聊天室。同是中國大陸網站的作品,一定要修改資料庫密碼和路徑。

修繕登記 [作者 : 萬芳國小] http://dd.ysps.tp.edu.tw/repair/index.htm

既然登記了就是希望能查閱追修時程,全校一份就好了,這一份我修改過部份內容,因為本校負責的人各有不同,於是分為三個表單,分別處理
〔教學設備報修】→總務處、設備組負責
〔電腦軟體報修】系統師、資訊組負責
〔電腦硬體報修】的報修→總務處負責。

報修完成會自動寄發電子郵件給負責人,工作完成也能自動寄發給報修人。

學生榮譽點數超級比一比 http://dd.ysps.tp.edu.tw/score/score.asp

這是以Java Script作資料的排序,滿好用的。SCRIPT下載 :http://www.dob.com.tw  ,本範例加上了ASP+MDB作為資料庫讀取動作,寫入/管理部分尚未完成。--黃自強]

WEB線上檔案管理系統 [作者 : Copyright by Dino Cho 2001] http://dd.ysps.tp.edu.tw/Alpha/Default.asp

超強網站管理員,可線上新增、刪除檔案和資料夾,並可線上編輯文字檔,包括asp程式,html文件等。整包丟入wwwroot再把mdb檔放在其他地方,程式中的資料庫路徑一定要改掉,密碼也要改掉。

使用請注意:
1.只有管理員才能用,虛擬目錄不適用。
2.本程式資料庫密碼要用鎖定開啟才能修改。[密碼為:****]

最後請把您寫的或修改的ASP程式分享給大家發表您的程式

 

柒、參考資料

石牌國小李忠憲老師 ASP 概論 http://www.spps.tp.edu.tw/documents/Detail.asp?TitleID=115 

SQL tutorial at W3School