當用戶從表單處完成遞交,如無問題已將注冊信息寫入數據庫,但有問題的是,如何防止用戶刷新頁面,這相當于將原有的信息再次寫入數據庫,在網絡上尋找解決方法,試用后將本人認為最管用的方法記下。
網絡中給出如下解決方式:
第一種:禁用提交按鈕
當用戶提交表單后,使用JAVASCRIPT腳本語言,將提交鈕禁用。
分析:如客戶端沒有開啟腳本功能就出現問題;這也僅是在表單處理前有用,防止用戶多次點擊提交鈕;現在很多網站都啟用驗證碼解決此問題了。
第二種:使用 Session
在第一次寫入數據庫代碼后,將Session標記;在數據庫代碼前判斷Session是否曾經標記過并與剛才的標記是否相等。
代碼:
Session("User") = True
Response.write "您剛才已經注冊過了……"
Else
...... '省略寫入數據庫部分
Session("User") = True
End if
分析:比較管用的;但Session默認時效為20分鐘,雖然可以設置時效長度,但由于網站服務器設置不同,也許達不到理想效果。
第三種:重新定向
注冊完畢后直接將網頁重新定向到其他頁面。
代碼:Response.Redirect "Index.html"
分析:使用此方法,需要配合客戶端腳本清除歷史(history)才行,沒有試用,因為用戶可以使用后退按鈕,繼續刷新。
第四種:禁止緩存
在寫入數據一頁最下邊添加下面的代碼,然后導向新頁,可以使用戶點擊后退按鈕后,頁面提示網頁過期。
代碼:
ASP:
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
ASP.NET:
Response.Buffer=true;
Response.ExpiresAbsolute=DateTime.Now.AddSeconds(-1);
Response.Expires=0;
Response.CacheControl="no-cache";
分析:試用后,發現一個問題,雖然表面看到網頁過期字樣,但在過期網頁上刷新,仍可以再次刷新多次注冊。
第五種:用彈出窗口
提交表單的時候彈出新窗口(在新窗口頁面完成數據庫的寫入),關閉本窗口。對于window.open()打開的窗口是無法用后退按鈕的。
第六種:調數據庫進行對比
這一種是得不償失的方法,因為會加重服務器的負擔,如果在表單沒有進行AJAX方式的驗證,這也算是一種必要的方法。
代碼:(假設已連接數據庫)
Dim Rs,SQL,UserId
UserId = Request("Userid") '從表單從取數據內容
If UserId <> "" then '不為空的時候
Set Rs=Server.CreateObject("Adodb.Recordset")
SQL = "Select Userid From 表 Where Userid='"& UserId &"'"
Rs.Open Sql, Conn, 2, 2
If Rs.Eof And Rs.Bof Then
Response.Write "沒有相同數據!"
Else
Response.Write "有相同數據!"
End If
Rs.Close
Set Rs = Nothing
Response.End
End If
經過測試,如果不想太費事,直接用第六種方法,用戶刷一次就對數據庫檢索一次,這種方式最大的弊端就是有可能把服務器累死;
由于,我采用了第二種方法,結合了第四種(效果不大),在代碼最前端加入了驗證由何處來本站的函數,這樣可以防止用戶自己在本機模仿網站表單提交數據(hi.baidu.com/76512/blog/item/b8d9be8f168d3aedf01f3680.html),也可以防止用戶在本站直接在網址末端加變量值刷新數據。
由于在表單處已加入隨機驗證碼,并已寫入Session中,在處理數據前,可以先檢測Session是否為空,空為已提交過了,不為空是第一次提交,在第一次提交后將該Session清空。
代碼:
If Session("RndNum") = ""
Response.Write "已提交過數據了呀!"
Else
...... '省略寫入數據庫代碼
Session("RndNum") = ""
End if
分析:只要是從正常的途徑遞交的表單,Session("RndNum")的數值不會為空的,從非正常途徑(比如說,直接打開網址,或在本機模擬表單遞交,或在網址后添加變量值,是無法寫入數據庫的。Session默認的20分鐘,清空后仍然符合邏輯。也不怕用戶打開幾個注冊頁面,來回刷新注冊。
禁用頁面緩存的幾種方法(靜態和動態)
1、在Asp頁面首部<head>加入
以下是引用片段:
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
Response.AddHeader "Pragma", "No-Cache" |
2、在HtML代碼中加入
以下是引用片段:
<HEAD>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
</HEAD> |
3、在重新調用原頁面的時候在給頁面傳一個參數 Href="****.asp?random()"
前兩個方法據說有時會失效,而第三種則是在跳轉時傳一個隨機的參數! 因為aspx的緩存是與參數相關的,如果參數不同就不會使用緩存,而會重新生成頁面,每次都傳一個隨機的參數就可以避免使用緩存。這個僅適用于asp&asp.net
4、在jsp頁面中可使用如下代碼實現無緩存:
以下是引用片段:
response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
response.setHeader("Pragma","no-cache"); //HTTP 1.0
response.setDateHeader ("Expires", 0); //prevents caching at the proxy server |
這些代碼加在<head> </head>中間具體如下
以下是引用片段:
<head>
<%
response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
response.setHeader("Pragma","no-cache"); //HTTP 1.0
response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
%>
</head> |
5、window.location.replace("WebForm1.aspx");
參數就是你要覆蓋的頁面,replace的原理就是用當前頁面替換掉replace參數指定的頁面。
這樣可以防止用戶點擊back鍵。使用的是javascript腳本,舉例如下:
a.html
以下是引用片段:
<html>
<head>
<title>a</title>
<script language="javascript">
function jump(){
window.location.replace("b.html");
}
</script>
</head>
<body>
<a href="javascript:jump()">b</a>
</body>
</html> |
b.html
以下是引用片段:
<html>
<head>
<title>b</title>
<script language="javascript">
function jump(){
window.location.replace("a.html");
}
</script>
</head>
<body>
<a href="javascript:jump()">a</a>
</body>
</html> |
前4種只是清空了cache,即存儲在Temporary Internet Files文件夾中的臨時文件,而第五種則是使用跳轉頁面文件替換當前頁面文件,并沒有清空cache,也就是說Temporary Internet Files產生了相關的臨時文件,兩者搭配使用真是清空緩存,必備良藥。