表单重复提交和禁用浏览器后退按钮问题

如何避免表单的重复提交和禁用浏览器后退按钮,是Web开发人员经常遇到的问题,如果你没有遇到这样的问题,或者你没注意到有这样的问题,那么你开发的Web页面肯定会存在隐蔽的问题。下面就这两个方面做个总结,有不对的地方,大家一定指出来~~

1、避免表单重复提交

避免表单重复提交就是在一个页面中,当用户提交了一个信息之后,有时可能因为网速等的问题,会导致用户多次点击,如果对于这种情况没有相应的处理方案,会导致有多条相同的记录被提交,如果是存到数据库中的话,就会导致数据库中有多条重复的记录。这行的问题,相信做Web开发的人员会遇到。

比如,对于某个博客下面的评论按钮,正常的情况应该是你点击“发表”按钮的时候,应该刷新评论的部分,但是如果网速较慢,或者其他原因,导致你“发表”按钮一直存在,你觉得自己提交没成功,所以会再次点击“发表”按钮,这样就会向服务器端发送两条一样的数据,导致数据库中的记录重复。

那么这样的问题怎么解决呢?

总的思路有两个。一是用js在前端处理;二是利用“令牌”机制在服务器端处理。

(1)前端js处理

在前端用页面中定义一个js变量hasCommited来标志用户时候已经提交了,如果没有提交,则允许用户提交,并将hasCommited置为true,这样用户即使再次点击,也只提交了一次。代码就不写了,思路很清晰,相信大家都能看懂。

(2)“令牌”机制

原理:当用户提交的时候,系统首先需要生成一个随机号,在服务器端进行保存并在jsp表单中绑定这个生成的随机号,当jsp表单提交时服务器端接收用户提交的这个随机号然后与服务器端保存的随机号进行对比,如果随即号相同的话,执行提交操作,并把服务器端保存的随机号销毁。如果不同的话提示用户重复提交。

关于“令牌”机制,一方面我们可以自己实现,稍微麻烦。另外,如果你使用了struts框架的话,struts是提供了“令牌”机制的,其原理和上面讲到的原理是一样的,只需要配置就可以了,其他的框架我不清楚,自己可以调研一下。

2、禁用浏览器后退按钮

问题描述:比如有一个在线测试的页面,当用户提交页面之后,调到呈现测试结果的页面(这个页面中会给出参考答案之类的),这个时候就不能让用户再后退到之前的测试页面进行重新做题,然后提交了。有人可能会说,将用户做两次这样的情况放到服务器端的业务部分进行验证不就行了吗?这样是可以的,但是却增加了服务器端的负担(要先去数据库中查找相应的记录,然后再判断)。我们想着是将这个功能尽量转移到客户端去做。下面是一些方法:

(1)

<scriptlanguage="JavaScript">

        javascript:window.history.forward(1); //我目前先用着这个

</script>

利用JS产生一个前进的动作,以抵消后退功能,这种方法应该是最简洁的,并且不需要考虑用户连点两次或多次后退的情况,缺点是当用户端禁用了JavaScript之后即失效。

(2)

<AHREF="logout.do"οnclick="javascript:location.replace(this.href); event.returnValue=false;">       

Logout(Back Disabled)

</A>

这种方法用链接页面的URL替换了当前的历史纪录,这样浏览历史记录中就不会有本页面,后退按钮将不能回到本页面。用户点击Logout链接注销并执行新页面,这时当用户点击后退按钮将不能回到本页,而是回到在本页之前打开的那个页面。

也就是说,这种方法清除的是最后一个访问历史记录,而不是全部的访问记录,这是该方法的一个缺点,当然可以在每一个业务页面都添加这段代码作为保护。另外,和上一种方法相同,当用户端禁用了JavaScript之后即失效。

3

<scriptlanguage="JavaScript">

functionlogout()

{

   window.close(true);

   window.open("logout.do");

}

</script>

<buttononClick="logout()">Logout</button>

这种方法比较偷懒,关掉浏览器再重新开,经过我的测试在视觉上几乎感觉不出来延时,同时又保证了后退按钮不可用(新窗口浏览器后退按钮为灰色),看起来似乎是个好方法,但缺点也比较明显:

首先,关闭和重开的浏览器窗口大小可能不同,用户可以明显看出这一过程,并且在一定程度上影响操作。

其次,同上,这是一个JavaScript方法。

以上方法都是针对后退按钮作出的反应,客户端浏览器需要打开JavaScript代码,下面尝试从另一角度来解决这一问题:

4、禁止缓存

<%

       response.setHeader("Cache-Control", "no-cache");

       

       response.setHeader("Cache-Control", "no-store");

       

       response.setDateHeader("Expires", 0);

       

       response.setHeader("Pragma", "no-cache");

%>

这种方法使用服务器端脚本,强制浏览器重新访问服务器下载页面,而不从缓存读取,结合strutsjsp页面中的<logic>标签实现重新定向。

以上各种方法都有一定的局限,虽然是一个小问题,可是考虑到页面安全的因素,却不得不重视。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值