基於的C/S模式單機版的考試系統,我記得那種單機版的考試系統在進入考試以后界面就會自動的最大化,從而使考生的界面只能停留在考試界面而不能進行其他的操作,那樣的話保證了考試系統的安全性。那么現在基於B/S模式下的在線考試系統的考試倒計時應該怎么樣做了。為了比較性的說明問題,我先把我的具體做法寫下來,大家一起來分析分析:
1.第一種方法:
我采用的是JavaScript來實現的
設計思想:在客戶端加載頁面時調用一段JS代碼,在這段代碼中設置一個函數,獲取當前時間,並每隔一秒調用以此該函數。
編寫代碼如下:
1 <html xmlns="http://www.w3.org/1999/xhtml">
2 <head>
3 <script language="javascript">
4 var timerID = null;
5 var timerRunning = false;
6 var leftsec = 0;
7 var leftmin = 2;
8 var lefthour = 0;
9 function stopclock() {
10 if (timerRunning)
11 clearTimeout(timerID);
12 timerRunning = false;
13 }
14 function startclock() {
15 stopclock();
16 showtime();
17 }
18 function showtime() {
19 var now = new Date();
20 var hours = now.getHours();
21 var minutes = now.getMinutes();
22 var seconds = now.getSeconds();
23 var timeValue = now.getYear() + "年" + (now.getMonth() + 1) + "月" + now.getDate() + "日" + ((hours >= 12) ? " 下午 " : " 上午 ");
24 var lefttime = ((hours > 12) ? hours - 12 : hours) + ((minutes < 10) ? "小時0" : "小時") + minutes + ((seconds < 10) ? "分0" : "分") + leftsec + "秒";
25 timeValue += ((hours > 12) ? hours - 12 : hours);
26 timeValue += ((minutes < 10) ? ":0" : ":") + minutes;
27 timeValue += ((seconds < 10) ? ":0" : ":") + seconds;
28 document.getElementById('thetime').innerHTML = timeValue;
29 timerID = setTimeout("showtime()", 500);
30
31 timerRunning = true;
32 }
33 </script>
34 <script language="JavaScript">
35 secs = 59;
36 wait = secs * 100;
37 minute = 89; //此處設定考試總時間
38 //循環調用秒的減方法 cycle();
39 function cycle() {
40 for (i = 0; i <= (wait / 100); i++) {
41 //每隔一秒更新一次
42 window.setTimeout("doUpdate(" + i + ")", i * 1000);
43 }
44 }
45 function doUpdate(num) {
46 if (num == (wait / 100)) {
47 cycle();
48 //三分鍾前提醒考生交卷
49 if (minute == 3) {
50 alert("還有三分鍾時間,請及時交卷!");
51 }
52 //時間到,提交表單
53 if (minute <= 0) {
54 document.exam.action = "login.aspx";
55 document.exam.submit();
56 }
57 minute--;
58 }
59 else {
60 wut = (wait / 100) - num;
61 //使得輸出格式為00:00
62 s = wut < 10 ? "0" + wut : wut;
63 m = minute < 10 ? "0" + minute : minute;
64 //將剩余時間顯示在頁面上
65 document.getElementById('lefttime').innerHTML = "剩余時間:" + m + "分" + s + "秒";
66 }
67 }
68 </script>
69 </head>
70 <body style="margin: 0px" scroll="no" onload="javascript:startclock(),cycle()">
71 <form id="form1" runat="server">
72 <table width="100%" height="100" border="0" cellspacing="0" cellpadding="0">
73 <tr>
74 <td height="58" valign="top">
75 <table width="100%" height="58" border="0" cellspacing="0" cellpadding="0" bgcolor="#4999ea">
76 <tr>
77 <td width="2%">
78 </td>
79 <td width="80%" height="58">
80 <div align="center">
81 <b><font color="white" size="5">考試系統計時及倒計時</font></b>
82 <br>
83 </div>
84 </td>
85 <td>
86 </td>
87 </tr>
88 </table>
89 </td>
90 </tr>
91 <tr>
92 <td>
93 <table width="100%" height="0" border="0" cellspacing="0" cellpadding="0">
94 <tr>
95 <td>
96 </td>
97 </tr>
98 <tr>
99 <td height="20" colspan="3" valign="middle" align="center" >
100 <table border="0" width="100%" valign="middle" height="30" align="center" bgcolor="#4999ea">
101 <tr align="left">
102 <td>
103 </td>
104 <td width="25%" align="right">
105
106 </td>
107 <td align="center" width="15%">
108 </td>
109 <td width="25%" align="left">
110 <span id="thetime" ></span>
111 </td>
112 <td width="20%" align="left">
113 <span id="lefttime" ></span>
114 </td>
115 <td width="5%">
116 </td>
117 </tr>
118 </table>
119 </td>
120 </tr>
121 </table>
122 </td>
123 </tr>
124 </table>
125 </form>
126 </body>
127 </html>
這種方法在做的時候,自己一開始是很認同的,因為最近接觸了JavaScript DOM編程藝術,了解了很多DOM世界的內容,所以感覺這是一種很好的方法。可是事后一想才意識到這種方法真的不可取,存在很大的漏洞,不知道讀者發現了沒有。那下面我們一起來分析一下,這種方法到底存在什么問題:
當你把這段代碼添加到你的頁面的時候,一調試運行,你會很欣慰的看到頁面上會顯示當前時間,並按照你設定的考試時間倒計時,沒錯,這是大家都能看到的。那么現在請你刷新一下頁面,請你告訴我發生了什么情況。沒錯,你看見了考試時間仍然在計時,但你再看看倒計時時間,是不是讓人很沮喪,他是不是又重新開始倒計時了呀。對,沒錯,這就是問題的所在,也就是說在用這種方法實現倒計時,是基於客戶端的,當用戶進行頁面刷新時,頁面的JS會重新加載,那么倒計時會回到初始狀態。這樣一來就失去了所謂的倒計時功能,而且這種方法還有一種漏洞就是用戶可以改掉本地機的時間,那么計時也會出現錯誤。
2.第二種方法:
我用的是AJAX來實現的
設計思想:在客戶端界面上用AJAX的Timer控件,注意使用AJAX必須使用的另外兩個AJAX控件也要一起使用。考試前由監考員做好所有相應的准備工作,考試開始由有監考員點擊開始考試按鈕,此時將開考狀態值保存在Application中,這是一個全局變量值,且是一個公有變量,session是每個用戶都有一個session,則無法實現共有變量的范圍,相應的則考試結束時,監考員點擊結束考試實現的是將Application中的狀態值變為false,當監考員發布監考命令時,在服務器上,將開考時間保存在服務器的Application中。那么把客戶端的Timer的屬性設置為1000ms,則客戶端每隔一秒到服務器去獲取一次服務器的時間,這樣得到一個時間差值,再利用考試時間來算考試所剩的時間,從而實現倒計時的模式。
編寫的代碼如下:
1 #region 計時器的實現
2 protected void Timer1_Tick(object sender, EventArgs e)
3 {
4 DateTime NowTime = System.DateTime.Now;
5 DateTime StartTime = Convert.ToDateTime(Application["StartTime"].ToString());
6 TimeSpan RemainTime = NowTime.Subtract(StartTime);
7 int hour = int.Parse(RemainTime.Hours.ToString());
8 int minute = int.Parse(RemainTime.Minutes.ToString());
9 int seconds = int.Parse(RemainTime.Seconds.ToString());
10 int time = 4;
11 string PaperInfo = Request.Cookies["PaperInfo"].Value;
12 if (hour >= 1)
13 {
14 time = (int.Parse(Request.Cookies[PaperInfo]["TotalTime"].ToString()) - 60 * hour - minute);
15 }
16 else
17 {
18 time = (int.Parse(Request.Cookies[PaperInfo]["TotalTime"].ToString()) - minute);
19 }
20 if (hour == 0 && time == 3 && seconds == 59)
21 {
22 Response.Write("<script language=javascript>alert('考試時間還剩下3分鍾,請做好交卷准備!');</script>");
23 }
24 if (hour == 0 && time == 0 && seconds == 59)
25 {
26 Response.Write("<script language=javascript>alert('考試時間到,試卷將自動提交!');window.close();</script>");
27 }
28 this.LabelRemainingTime.Text = (time - 1).ToString() + "分鍾" + (60 - seconds).ToString() + "秒";
29
30 }
31 #endregion
利用AjAx的Timer控件技術,那么相對於來說,是比較安全的一種做法,但這種方法會增大對服務器的請求量,會給服務器造成一定的壓力。所以特定的方法也只能在特定的情況下適用,具體還是得看運行環境。