• 防止表单重复提交


    一:在客户端通过javascript防止表单重复提交

     1 <!DOCTYPE html>
     2 <html>
     3   <head>
     4     <title>form.html</title>
     5     <meta name="keywords" content="keyword1,keyword2,keyword3">
     6     <meta name="description" content="this is my page">
     7     <meta name="content-type" content="text/html; charset=UTF-8">
     8 <script type="text/javascript">
     9               var isCommitted = false;
    10               function doSubmit()
    11               {
    12                   if(isCommitted==false){
    13                       isCommitted = true;
    14                       return true;
    15                   }
    16                   return false;
    17               }
    18 
    19 </script>
    20   </head>
    21   <body>
    22   <form action="/test/servlet/FormServlet" method="post"  onsubmit="return dosubmit()">
    23   用户名:<input type="text" name="username"/>
    24   <br>
    25   <input type="submit" value="提交">
    26   </form>
    27  <br>
    28   </body>
    29 </html>

    还可以提交过后将提交按钮变灰,无法提交

     1 <!DOCTYPE html>
     2 <html>
     3   <head>
     4     <title>form.html</title>
     5     <meta name="keywords" content="keyword1,keyword2,keyword3">
     6     <meta name="description" content="this is my page">
     7     <meta name="content-type" content="text/html; charset=UTF-8">
     8 <script type="text/javascript">
     9 function dosubmit(){
    10     var submit = document.getElementById("submit");
    11     submit.disabled= "disabled";
    12     return true;
    13 
    14 }
    15 </script>
    16   </head>
    17   <body>
    18   <form action="/test/servlet/FormServlet" method="post"  onsubmit="return dosubmit()">
    19   用户名:<input type="text" name="username"/>
    20   <br>
    21   <input type="submit" value="提交"  id="submit">
    22   </form>
    23  <br>
    24   </body>
    25 </html>

    其实只在前台用javascript是禁不掉恶意用户的恶意操作的,必须在服务端处理。如用户单击”刷新”,或单击”后退”再次提交表单,将导致表单重复提交。但在服务端处理的同时,客户端也要处理,因为javascript最大的好处就是提升用户体验。

    二利用session防止表单重复提交

    表单页面由servlet程序生成,servlet为每次产生的表单页面分配一个唯一的随机标识号,并在FORM表单的一个隐藏字段中设置这个标识号,同时在当前用户的Session域中保存这个标识号。
    当用户提交FORM表单时,负责处理表单提交的serlvet得到表单提交的标识号,并与session中存储的标识号比较,如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。
    在下列情况下,服务器程序将拒绝用户提交的表单请求:
    存储Session域中的表单标识号与表单提交的标识号不同
    当前用户的Session中不存在表单标识号
    用户提交的表单数据中没有标识号字段
     1 package cn.itcast.form;
     2 
     3 import java.io.IOException;
     4 import java.io.PrintWriter;
     5 import java.security.MessageDigest;
     6 import java.security.NoSuchAlgorithmException;
     7 import java.util.Random;
     8 
     9 import javax.servlet.ServletException;
    10 import javax.servlet.http.HttpServlet;
    11 import javax.servlet.http.HttpServletRequest;
    12 import javax.servlet.http.HttpServletResponse;
    13 
    14 import sun.misc.BASE64Encoder;
    15 
    16 //负责产生表单
    17 public class FormServlet extends HttpServlet {
    18 
    19     public void doGet(HttpServletRequest request, HttpServletResponse response)
    20             throws ServletException, IOException {
    21 
    22         response.setContentType("text/html;charset=UTF-8");
    23         PrintWriter out = response.getWriter();
    24         
    25         String token = TokenProccessor.getInstance().makeToken();
    26         request.getSession().setAttribute("token", token);  //在服务器端保存随机数
    27         
    28         out.println("<form action='/day07/servlet/DoFormServlet' method='post'>");
    29             out.write("<input type='hidden' name='token' value='"+token+"'>");
    30             out.println("用户名:<input type='text' name='username'>");
    31             out.println("<input type='submit' value='提交'>");
    32         out.println("</form>");
    33     }
    34 
    35     public void doPost(HttpServletRequest request, HttpServletResponse response)
    36             throws ServletException, IOException {
    37 
    38         doGet(request, response);
    39     }
    40 }
    41 //工具类生成表单标识号
    42 class TokenProccessor{
    43     
    44     /*
    45      *单态设计模式(保证类的对象在内存中只有一个)
    46      *1、把类的构造函数私有
    47      *2、自己创建一个类的对象
    48      *3、对外提供一个公共的方法,返回类的对象
    49      * 
    50      */
    51     private TokenProccessor(){}
    52     
    53     private static final TokenProccessor instance = new TokenProccessor();
    54     
    55     public static TokenProccessor getInstance(){
    56         return instance;
    57     }
    58     
    59     
    60     public String makeToken(){  //checkException
    61         
    62         //  7346734837483  834u938493493849384  43434384
    63         String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
    64         //产生固定长度的随机数
    65         //数据指纹   128位长   16个字节  md5
    66         try {
    67             MessageDigest md = MessageDigest.getInstance("md5");
    68             byte md5[] =  md.digest(token.getBytes());
    69             
    70             //base64编码--任意二进制编码明文字符   
    71             BASE64Encoder encoder = new BASE64Encoder();
    72             return encoder.encode(md5);
    73             
    74         } catch (NoSuchAlgorithmException e) {
    75             throw new RuntimeException(e);
    76         }
    77         
    78     }
    79     
    80 }
     1 package cn.itcast.form;
     2 
     3 import java.io.IOException;
     4 import java.io.PrintWriter;
     5 
     6 import javax.servlet.ServletException;
     7 import javax.servlet.http.HttpServlet;
     8 import javax.servlet.http.HttpServletRequest;
     9 import javax.servlet.http.HttpServletResponse;
    10 
    11 public class DoFormServlet extends HttpServlet {
    12 
    13     public void doGet(HttpServletRequest request, HttpServletResponse response)
    14             throws ServletException, IOException {
    15 
    16         
    17         boolean b = isToken(request);  //判断用户是否是重复提交
    18         if(b==true){
    19             System.out.println("请不要重复提交");
    20             return;
    21         }
    22         
    23         request.getSession().removeAttribute("token");
    24         //移除session中的随机数
    25         System.out.println("处理用户提交请求!!");
    26         
    27     }
    28 
    29     private boolean isToken(HttpServletRequest request) {
    30         
    31         String client_token = request.getParameter("token");//客户机带过来的随机数
    32         //没有带随机数过来,说明是恶意用户用自己的form提交到服务端
    33         if(client_token==null){
    34             return true;
    35         }
    36         //带了随机数过来,考察服务器保存的随机数
    37         String server_token = (String) request.getSession().getAttribute("token");
    38         //服务器没有保存随机数,说明服务器处理过这个表单,处理表单后,将session中的这个随机数移除了
    39         if(server_token==null){
    40             return true;
    41         }
    42         //用户带过来的随机数和服务器存的不一样,说明是恶意提交
    43         if(!client_token.equals(server_token)){
    44             return true;
    45         }
    46         //正常提交
    47         return false;
    48     }
    49 
    50     public void doPost(HttpServletRequest request, HttpServletResponse response)
    51             throws ServletException, IOException {
    52 
    53         doGet(request, response);
    54     }
    55 
    56 }
  • 相关阅读:
    武道之路-炼体期五重天中期
    武道之路-炼体期五重天
    武道之路-炼体期四重天巅峰
    修改Oracle监听端口
    完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
    Create Linked Server SQL Server 2008
    Oracle:ODP.NET Managed 小试牛刀
    jquery ajax跨域请求webservice webconfig配置
    oracle 11g ORA-12541: TNS: 无监听程序 (DBD ERROR: OCIServerAttach)
    oracle 11g 一直提示 严重: 监听程序未启动或数据库服务未注册到该监听程序
  • 原文地址:https://www.cnblogs.com/yyz666/p/4061805.html
Copyright © 2020-2023  润新知