防止表单重复提交

在注册表单中,我们会遇到表单重复提交

在这里有两种解决方案,一种是在前端阻止,一种在服务器端阻止

1.在javaScript里阻止表单重复提交

<html>  
<head>  
<meta charset="UTF-8">  
<title>Insert title here</title>  
<script type="text/javascript">  
    //定义一个全局变量  
    //这个变量用来记住表单是否提交过,提交过便置为true  
    var iscommitted = false;  
    function dosubmit(){  
        //当表单为false时  便返回true  并将iscommitted改为true  
        if(!iscommitted){  
            iscommitted = true;  
            return true;  
        }  
        return false;  
    }  
</script>  
</head>  
<body>  
    <!--   
        表单添加一个onsubmit事件   
        该事件调用的方法返回true时便提交表单  
    -->  
    <form action="/sd/dfs" method="post" οnsubmit="return dosubmit()">  
        用户名:<input type="text" name="username" />  
        <input type="submit" value="提交">  
    </form>  
</body>  
</html>

在实际开发中javaScript的方法是有漏洞的(如果有人想重复提交还是有办法重复提交的)

所以我们还需要在服务器端一起阻止表单重复提交


2.在服务器端阻止表单重复提交

思路:表单由程序输出给浏览器,在每个表单里设置唯一的表单号,并且将表单号存储在服务器。提交表单后,服务器拿出表单号进行比较,如果有便表示没有提交过,然后删除表单号。

我们写一个servlet用于产生表单号

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        //产生随机数(表单号)  我们需要创建一个随机数的发生器  
        TokenProcessor instance = TokenProcessor.getInstance();  
        String token = instance.generateToken();  
        //将随机数存入session   方便到时候 验证  
        HttpSession session = request.getSession();  
        session.setAttribute("token", token);  
        //请求转发  
        request.getRequestDispatcher("/form.jsp").forward(request, response);  
          
    }  

创建一个随机数生产器

//创建一个随机数的发生器  
class TokenProcessor{//token:令牌  
    /*  
     * 单例设计模式  
     *  1.把构造方法私有  
     *  2.自己创建一个  
     *  3.对外暴露一个方法,允许获取上面创建的对象  
     */  
    private TokenProcessor(){}  
    private static final TokenProcessor instance = new TokenProcessor();  
      
    public static TokenProcessor getInstance(){  
        return instance;  
    }  
    //产生随机数  
    public String generateToken(){  
        //获取当前时间  +  随机数  
        String token =  System.currentTimeMillis()+ new Random().nextInt()+"";  
  
     try {  
            //得到数据的摘要(指纹)  创建实例 "md5"算法  
            MessageDigest md = MessageDigest.getInstance("md5");  
            byte[] md5 = md.digest(token.getBytes());  
            /* base64编码  
             * 然后数经过base64算法编码返回的都是一个明文字符串  
             * 会把三个字节变成四个字节   每三个字节变成四个字节  
             */  
            BASE64Encoder encoder = new BASE64Encoder();  
            return encoder.encode(md5);  
         } catch (NoSuchAlgorithmException e) {  
            throw new RuntimeException(e);  
        }  
    }  
}  

创建form表单

<%@ page language="java" contentType="text/html; charset=UTF-8"  
    pageEncoding="UTF-8"%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
<title>Insert title here</title>  
</head>  
<body>  
    <form action="/sd/dfs" method="post" >  
        <input type="hidden" name="token" value="${token}">  
        用户名:<input type="text" name="username" /><br/>  
        <input type="submit" value="提交">  
    </form>  
</body>  
</html>  

运行:................



当表单提交后,它会进入此servlet 进行表单号的判断来确定它是否是合理的请求

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
        //判断表单号是否有效  
        boolean b = isTokenValid(request);  
        if(!b){  
            System.out.println("请不要重复提交");  
            return;  
        }  
        request.getSession().removeAttribute("token");  
        System.out.println("向数据库中注册用户");  
    }  
    //判断表单号是否有效  
    private boolean isTokenValid(HttpServletRequest request) {  
        //客户机带过来的表单号  
        String client_token = request.getParameter("token");  
        if(client_token==null){  
            return false;  
        }  
        //获取session里的表单号  
        String server_token = (String) request.getSession().getAttribute("token");  
        if(server_token==null){  
            return false;  
        }  
        //判断客户机的表单号与session里的表单号是否不相等  
        if(!server_token.equals(client_token)){  
            return false;  
        }  
        return true;  
    }  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值