随笔-124  评论-49  文章-56  trackbacks-0

当用户从表单处完成递交,如无问题已将注册信息写入数据库,但有问题的是,如何防止用户刷新页面,这相当于将原有的信息再次写入数据库,在网络上寻找解决方法,试用后将本人认为最管用的方法记下。

网络中给出如下解决方式:

第一种:禁用提交按钮

当用户提交表单后,使用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产生了相关的临时文件,两者搭配使用真是清空缓存,必备良药。


 

posted on 2010-06-21 17:33 junly 阅读(2631) 评论(1)  编辑  收藏 所属分类: jsp/servlet

评论:
# re: 防止页面多次刷新提交表单(转) 2010-07-10 10:00 | Alice
受教  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: