Web应用中避免Form重复提交的三种方案

Web应用中避免Form重复提交的三种方案
2007-08-21 18:29
Web应用中重复提交的问题的三种解决方案

前两种是利用javascript,后面一种是在使用Struts的情况下的参考实现

  • 1 javascript ,设置一个变量,只允许提交一次。
    1.  
    2. <script language="javascript">
    3.      var checkSubmitFlg = false;
    4.      function checkSubmit() {
    5.       if (checkSubmitFlg == true) {
    6.          return false;
    7.        }
    8.        checkSubmitFlg = true;
    9.       return true;
    10.     }
    11.     document.ondblclick = function docondblclick() {
    12.      window.event.returnValue = false;
    13.     }
    14.     document.onclick = function doconclick() {
    15.        if (checkSubmitFlg) {
    16.           window.event.returnValue = false;
    17.         }
    18.     }
    19. </script>

    <html:form action="myAction.do" method="post" οnsubmit="return checkSubmit();">

  • 2 还是javascript,将提交按钮或者image置为disable

    1.  
    2.    <html:form action="myAction.do" method="post"  
    3.      οnsubmit="getElById('submitInput').disabled = true; return true;">   
    4.    
    5.    <html:image styleId="submitInput" src="images/ok_b.gif" border="0" />
    6.    
    7.    </html:form>
    8.  


  • 3 利用struts的同步令牌机制

    利用同步令牌(Token)机制来解决Web应用中重复提交的问题,Struts也给出了一个参考实现。
 基本原理:

服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,
看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给
客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次
提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
  1.  
  2. if (isTokenValid(request, true)) {
  3.     // your code here
  4.     return mapping.findForward("success");
  5. } else {
  6.      saveToken(request);
  7.     return mapping.findForward("submitagain");
  8. }

Struts根据用户会话ID和当前系统时间来生成一个唯一(对于每个会话)令牌的,具体实现可以参考
TokenProcessor类中的generateToken()方法。

1. //验证事务控制令牌,<html:form >会自动根据session中标识生成一个隐含input代表令牌,防止两次提交
2. 在action中:
  1.  
  2.        //<input type="hidden" name="org.apache.struts.taglib.html.TOKEN"
  3.        //   value="6aa35341f25184fd996c4c918255c3ae">
  4.        if (!isTokenValid(request))
  5.             errors.add(ActionErrors.GLOBAL_ERROR,
  6.                       new ActionError("error.transaction.token"));
  7.         resetToken(request); //删除session中的令牌

3. action有这样的一个方法生成令牌
  1.  
  2.    protected String generateToken(HttpServletRequest request) {
  3.  
  4.         HttpSession session = request.getSession();
  5.        try {
  6.            byte id[] = session.getId().getBytes();
  7.            byte now[] =
  8.                new Long(System.currentTimeMillis()).toString().getBytes();
  9.            MessageDigest md = MessageDigest.getInstance("MD5");
  10.             md.update(id);
  11.             md.update(now);
  12.            return (toHex(md.digest()));
  13.         } catch (IllegalStateException e) {
  14.            return (null);
  15.         } catch (NoSuchAlgorithmException e) {
  16.            return (null);
  17.         }
  18.     }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值