`
jerry_chiang
  • 浏览: 28180 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论
阅读更多
       偶然发现了一个小问题,在有些人做的信息系统中,在浏览器上选择后退或刷新时,如果在编写程序的时候不处理,很容易导致重复提交,这样原本像服务器发送的“发表帖子”的命令,就会被发送两次或多次,导致在数据库中插入多条记录。那么如何避免这种情况呢?

       其实我们可以在发表帖子的方法开头加上一个if判断即可。
       if (isRedo(request,"topic_add")) {
             //跳转到提示页面,提示用户已经提交过了
        }

       其中isRedo方法定义为:
       private boolean isRedo(HttpServletRequest request, String key) {
             String value = (String) request.getSession().getAttribute(key);
             if (value == null) {
                   return true;
             } else {
                   request.getSession().removeAttribute(key);
             }
       }

       该方法,首先判断session中是否含有名为key的变量。如果没有,就判断是“重复提交”;否则,就判断为“第一次处理”,并将该属性 从session变量中删除,那么在浏览器后退或刷新导致重复提交的时候,再次调用该方法就会发现该属性为空,因此判断为“重复提交”。
       其中,key是在发表帖子的方法中写入到session中去的:
       session.setAttribute("topic_add","topic_add");
       也就是说在页面请求的时候,就会把key写入到session中,并在第一次提交的时候由程序把key从session中删除。从而达到判断是否重复提交的目的。

       除了这种简单的方法以外,一般通常利用Struts同步令牌(Token)机制来解决Web应用中的重复提交问题。该方法的基本原理是:服 务器端在处理到达的request之前,会将request中的Token值与保存在当前用户session中的令牌值进行比较,看是否匹配。在处理完该 request后,且在response发送给客户端之前,将会产生一个新的 Token,该Token除传给客户端以外,也会将用户session中保 存的旧的Token进行替换。这样,如果用户会退到刚才的提交页面并再次提交的话,客户端传过来的Token值和服务器端的不一致,从而有效地防止了重复 提交地发生。利用Struts这种方法和前面给出的方法原理上是一样的,只是在具体实现上不同而已。

初来乍到,欢迎讨论:)
分享到:
评论
17 楼 blu3leaf 2007-03-30  
恩恩~~初来乍到,问个弱智问题,重定向是否可以按后退键返回到提交页面?
16 楼 ahuaxuan 2007-03-30  
一般来说就是令牌环和重定向了,令牌环在struts和webwork2中都有支持,其他框架我不知道,但是如果是jsp+servlet的用法,可以直接hidden值在页面上,有验证码的话肯定不可能重复提交了,所以遇到重复提交的问题讲来讲去就这么几种思路
15 楼 Qieqie 2007-03-30  
链接可以是js函数,在js中做个全局标志变量模拟disabled啦
14 楼 jamesby 2007-03-30  
Qieqie 写道
提交时:
jamesby 写道
目前我的做法是用一个Hidden域,默认为0,onclick后将值设置为1.然后处理页面显示的时候用redirect方式避免F5操作!



提交后:
tomgreenintel 写道
重定向不就行了吗?



就这样用!


加入验证码的表单不要考虑重复刷新的问题
提交后用redirect方式就不用管提交后如何了,

主要是有些提交操作是用链接而不是用button,这样前面说的disabled对我来说就没有用了。

13 楼 Qieqie 2007-03-30  
提交时:
jamesby 写道
目前我的做法是用一个Hidden域,默认为0,onclick后将值设置为1.然后处理页面显示的时候用redirect方式避免F5操作!



提交后:
tomgreenintel 写道
重定向不就行了吗?



就这样用!


加入验证码的表单不要考虑重复刷新的问题
12 楼 gigi311 2007-03-30  
我认为js的disable属性虽然能使后台得不到控件的值,或者是按钮看起来不可用,但根本没办法防止人家进行刷新,刷新其实就是把刚提交的那个request包又进行了一次提交。所以,还是在后台用做标记的方法来阻止的比较好,也比较常用些.我是这么认为的
11 楼 jianfeng008cn 2007-01-23  
together 写道
最保险的方式是使用弹出窗口。提交完以后窗口就关掉。这样不管你想怎么重新提交,都没戏。



用js做前台处理或者
弹出窗口虽方便,本身限制太多,复杂表单需特殊处理,还不如一个简单通用的方案来得好,再说弹出窗口也解决不了别人的恶意攻击啊,好比表单只用js作验证一样,最好的办法还是ww那样bs两端配合解决吧?

最近陪朋友到中国移动去买手机,就发生了提交2次扣了2次钱的事,搞得贼麻烦,浪费了我们好多时间(我在边上偷偷瞄了几眼他们的系统界面)。
10 楼 together 2007-01-23  
最保险的方式是使用弹出窗口。提交完以后窗口就关掉。这样不管你想怎么重新提交,都没戏。
9 楼 tomgreenintel 2007-01-22  
重定向不就行了吗?
8 楼 憨五弟 2007-01-22  
实现方法很多
感觉用js来disable按钮的方式最简单,用得也很多
7 楼 jamesby 2007-01-21  
目前我的做法是用一个Hidden域,默认为0,onclick后将值设置为1.然后处理页面显示的时候用redirect方式避免F5操作!
6 楼 ppeter 2007-01-21  
http://book.csdn.net/bookfiles/175/1001757886.shtml,webwork中使用表单标记(token)防止重复提交.
5 楼 LucasLee 2007-01-21  
bigpanda 写道
用javascript提交,onclick之后disable按钮,个人觉得是个非常简单有效的方法。

对,我也认为这个比Struts token更合适。Struts Token不适合打开多个表单,分别提交的情况,如果设置多个有效Token,我觉得无法合理的判断有效的Token.
但Javascript方式,同时要设置浏览器不缓存页面。
4 楼 bigpanda 2007-01-20  
用javascript提交,onclick之后disable按钮,个人觉得是个非常简单有效的方法。
3 楼 kevinStar 2007-01-20  
<p>就像楼上说的,那么lz的方法就失效了。我的做法是让提交按钮失效和token或者再从数据库中查询一遍。</p>
<p>但数据库中再查一遍,我一直没用过。因为我感觉这个代价太高了。</p>
<p>这方面也困惑我好久了,一直也没找到好的解决办法。希望有经验的人指导一下。</p>
<p>还有一种办法是用标志来进行判断是否重复提交(类似事务),是以前看到的后来找不到了。</p>
2 楼 galaxystar 2007-01-20  
<br/>
<strong>jerry_chiang 写道:</strong><br/>
<div class='quote_div'>       偶然发现了一个小问题,在有些人做的信息系统中,在浏览器上选择后退或刷新时,如果在编写程序的时候不处理,很容易导致重复提交,这样原本像服务器发送的“发表帖子”的命令,就会被发送两次或多次,导致在数据库中插入多条记录。那么如何避免这种情况呢?<br/>
<br/>
       其实我们可以在发表帖子的方法开头加上一个if判断即可。<br/>
       if (isRedo(request,"topic_add")) {<br/>
             //跳转到提示页面,提示用户已经提交过了<br/>
        }<br/>
<br/>
       其中isRedo方法定义为:<br/>
       private boolean isRedo(HttpServletRequest request, String key) {<br/>
             String value = (String) request.getSession().getAttribute(key);<br/>
             if (value == null) {<br/>
                   return true;<br/>
             } else {<br/>
                   request.getSession().removeAttribute(key);<br/>
             }<br/>
       }<br/>
<br/>
       该方法,首先判断session中是否含有名为key的变量。如果没有,就判断是“重复提交”;否则,就判断为“第一次处理”,并将该属性 从session变量中删除,那么在浏览器后退或刷新导致重复提交的时候,再次调用该方法就会发现该属性为空,因此判断为“重复提交”。<br/>
       其中,key是在发表帖子的方法中写入到session中去的:<br/>
       session.setAttribute("topic_add","topic_add");<br/>
       也就是说在页面请求的时候,就会把key写入到session中,并在第一次提交的时候由程序把key从session中删除。从而达到判断是否重复提交的目的。<br/>
<br/>
       除了这种简单的方法以外,一般通常利用Struts同步令牌(Token)机制来解决Web应用中的重复提交问题。该方法的基本原理是:服 务器端在处理到达的request之前,会将request中的Token值与保存在当前用户session中的令牌值进行比较,看是否匹配。在处理完该 request后,且在response发送给客户端之前,将会产生一个新的 Token,该Token除传给客户端以外,也会将用户session中保 存的旧的Token进行替换。这样,如果用户会退到刚才的提交页面并再次提交的话,客户端传过来的Token值和服务器端的不一致,从而有效地防止了重复 提交地发生。利用Struts这种方法和前面给出的方法原理上是一样的,只是在具体实现上不同而已。<br/>
<br/>
初来乍到,欢迎讨论:)</div>
<br/>
<br/>
如果用户后退,改了下表单的内容呢?你判断它是重复提交?<br/>
1 楼 jamesby 2007-01-20  
jerry_chiang 写道
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 偶然发现了一个小问题,在有些人做的信息系统中,在浏览器上选择后退或刷新时,如果在编写程序的时候不处理,很容易导致重复提交,这样原本像服务器发送的&ldquo;发表帖子&rdquo;的命令,就会被发送两次或多次,导致在数据库中插入多条记录。那么如何避免这种情况呢?<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其实我们可以在发表帖子的方法开头加上一个if判断即可。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(isRedo(request,&quot;topic_add&quot;))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//跳转到提示页面,提示用户已经提交过了<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中isRedo方法定义为:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;boolean&nbsp;isRedo(HttpServletRequest&nbsp;request,&nbsp;String&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;value&nbsp;=&nbsp;(String)&nbsp;request.getSession().getAttribute(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(value&nbsp;==&nbsp;null)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request.getSession().removeAttribute(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;该方法,首先判断session中是否含有名为key的变量。如果没有,就判断是&ldquo;重复提交&rdquo;;否则,就判断为&ldquo;第一次处理&rdquo;,并将该属性 从session变量中删除,那么在浏览器后退或刷新导致重复提交的时候,再次调用该方法就会发现该属性为空,因此判断为&ldquo;重复提交&rdquo;。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中,key是在发表帖子的方法中写入到session中去的:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.setAttribute(&quot;topic_add&quot;,&quot;topic_add&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;也就是说在页面请求的时候,就会把key写入到session中,并在第一次提交的时候由程序把key从session中删除。从而达到判断是否重复提交的目的。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;除了这种简单的方法以外,一般通常利用Struts同步令牌(Token)机制来解决Web应用中的重复提交问题。该方法的基本原理是:服 务器端在处理到达的request之前,会将request中的Token值与保存在当前用户session中的令牌值进行比较,看是否匹配。在处理完该 request后,且在response发送给客户端之前,将会产生一个新的&nbsp;Token,该Token除传给客户端以外,也会将用户session中保 存的旧的Token进行替换。这样,如果用户会退到刚才的提交页面并再次提交的话,客户端传过来的Token值和服务器端的不一致,从而有效地防止了重复 提交地发生。利用Struts这种方法和前面给出的方法原理上是一样的,只是在具体实现上不同而已。<br />
<br />
初来乍到,欢迎讨论:)
Struts的Token在Session只保存一个属性,我用open方式打开多个窗口,结果经常提交失败.应该每次请求在session中保存的token的属性名不同更合理一些.

相关推荐

    SSH笔记-数据验证、上传下载、避免表单重复提交、自定义拦截器

    接着,我们讨论如何避免表单重复提交。在Web应用中,用户可能无意或有意地多次点击提交按钮,导致数据库中出现重复数据。为了防止这种情况,通常会在服务器端或客户端采取措施。在Struts2中,可以使用Session来存储...

    防止Layui form表单重复提交的实现方法

    下面详细解释几种防止Layui表单重复提交的方法。 首先,在HTML表单中,为了避免在提交时页面刷新导致的重复提交,可以在标签中使用onsubmit="return false;"属性。这个属性的作用是在表单提交时返回false,阻止...

    javascript方式防止表单重复提交

    在Web开发中,表单重复提交是一个常见的问题,可能导致数据的冗余或错误。JavaScript作为客户端脚本语言,可以通过多种策略来防止用户意外或恶意地多次提交表单。以下是一些关键的知识点: 1. **禁用提交按钮**:最...

    [Jsp]防止页面表单重复提交的解决方法

    本篇文章将探讨如何有效地防止JSP页面中的表单重复提交,确保系统的稳定性和数据的准确性。 一、理解表单重复提交的问题 当用户点击提交按钮后,由于网络延迟或浏览器刷新等原因,可能导致同一份表单数据多次发送...

    springboot2.1+redis+拦截器 防止表单重复提交

    在现代Web应用开发中,防止表单重复提交是一项重要的任务,因为这可能导致数据不一致性和服务器资源浪费。本文将深入探讨如何使用Spring Boot 2.1、Redis和拦截器来实现这一功能。以下是对这个主题的详细解释: ...

    Struts2解决表单重复提交

    在Web应用中,表单重复提交是一种常见的问题。通常,这种问题发生在用户在提交表单后,由于网络延迟或用户的误操作再次点击提交按钮,或者在表单提交后刷新浏览器页面。这两种情况都可能导致服务器接收到重复的请求...

    防止表单重复提交(asp.net )

    在ASP.NET web应用程序中,表单重复提交是一个常见的问题,可能导致数据不一致或者数据库操作的冗余。为了确保用户在提交表单时不会无意或有意地多次发送请求,我们需要实施有效的防止表单重复提交的策略。以下是...

    用Struts的Token机制解决表单重复提交.doc

    通过上述介绍可以看出,Struts的Token机制提供了一种简单而有效的解决方案来避免表单重复提交的问题。开发者只需要遵循一定的编码规范和逻辑结构,就可以轻松地在自己的项目中实现这一机制。这对于提高Web应用的数据...

    防止表单重复提交

    然而,如果没有适当处理,可能会出现表单重复提交的问题,这可能导致数据的不一致性和服务器资源的浪费。本篇文章将深入探讨如何防止表单重复提交,主要关注于基于Struts2框架的解决方案。 首先,理解表单重复提交...

    Java web解决表单重复提交问题

    3.什么情况需要避免表单重复提交?  什么叫表单提交问题,说白了,是同一份信息,重复的提交给服务器。  那么,在什么情况下回产生表单重复提交的情况呢?  给大家列举以下情况:  1.点击F5刷新页面:当用户...

    表单重复提交问题1

    在Web开发中,表单重复提交是一个常见的问题,它可能会导致数据冗余或者不一致,尤其是在处理关键操作如交易、订单或用户注册时。这里我们深入探讨这个问题,并提供解决方案。 标题"表单重复提交问题1"所涉及的核心...

    Struts之Token解决表单那重复提交

    表单重复提交可能发生在用户点击提交按钮后,由于网络延迟或刷新页面等原因,导致请求被多次发送到服务器。如果不加以控制,可能会导致同一份数据被处理多次,从而对数据库造成不必要的影响。 二、Token机制的原理 ...

    ASP.NET中防止刷新页面造成表单重复提交

    ### ASP.NET中防止刷新页面造成表单重复提交 在Web应用程序开发中,特别是在使用ASP.NET进行网站构建时,一个常见的问题是表单重复提交。这通常发生在用户通过按下浏览器的F5键来刷新页面的情况下,此时之前的表单...

    试谈在Web应用中如何避免表单的重复提交.pdf

    如何避免Web应用中的表单重复提交 在Web应用中,避免表单的重复提交是一个棘手的问题。用户在提交表单时可能因为网络速度的原因,或者网页被恶意刷新,导致同一条记录重复插入到数据库中。这篇文章将探讨如何从...

    java实现防止表单重复提交

    服务器端避免表单的重复提交,利用同步令牌来解决重复提交的基本原理如下:(1)用户访问提交数据的页面,服务器端在这次会话中,创建一个session对象,并产生一个令牌值,将这个令牌值作为隐藏输入域的值,随表单一起发送到...

    使用struts的同步令牌避免form的重复提交

    ### 使用Struts的同步令牌避免表单重复提交 #### 一、使用方法 为了有效地防止Web应用程序中的表单重复提交问题,Struts框架提供了一种简单而强大的解决方案——同步令牌模式(Synchronization Token Pattern, STP...

    element-ui如何防止重复提交的方法步骤

    在IT行业中,尤其是在前端开发领域,防止用户重复提交是一项重要的任务,这有助于避免因网络延迟或用户误操作导致的数据混乱。Element-UI,一个流行的Vue.js组件库,提供了多种方式来处理这个问题。以下是如何在使用...

    spring boot 防止重复提交实现方法详解

    Spring Boot 防止重复提交是指在用户提交表单或请求时,防止同一客户端在短时间内对同一 URL 的重复提交,从而避免服务器端的处理压力和数据的一致性问题。下面将详细介绍 Spring Boot 防止重复提交实现方法的相关...

    php解决和避免form表单重复提交的几种方法

    PHP作为常用的服务器端脚本语言,提供多种方式来处理和避免表单重复提交的问题。以下将详细介绍几种常用的方法: 1. **利用JavaScript禁用提交按钮** 当用户点击提交按钮后,通过JavaScript将按钮设置为禁用状态,...

Global site tag (gtag.js) - Google Analytics