表单重复提交--->使用Session防止表单重复提交

  表单重复提交一般情况下有3种场景:

  1> 网络延迟时,不断点击submit按钮

  2> 表单提交后,用户点击刷新

  3> 表单提交后,用户返回表单页面重新提交

针对这三种场景,在网上查阅各种方案后,感觉以下方案能够比较好的解决问题

第一种:

  javascript方案 (只能用于第一种场景):

	<form action = "doForm" id ="f" method = "post" >
		<input type = "text" name= "username" autocomplete = "off"/>
		<input type = "submit" id = "submit" value="提交" onclick = "checkSubmit()">
	</form>

  在js 中只要有标记变化就可以,可以使boolean,也可以是数值

        var submitFlag = false;
	function checkSubmit(){
		alert(submitFlag);
		if(!submitFlag){
			submitFlag = true;
			return true;
		}
		return false;
	}

第二种:

  在表单提交后,将按钮设为不可用(只适用于第一种场景):

 function checkSubmit(){
        document.getElementById("submit").disabled = "disabled";
        return true;
 } 

第三种:场景二 和 场景三 在客户端没办法解决,只能依赖服务器端解决,而此时就要用session了

  具体方法:在服务器端生成一个标记号:Token(令牌)。发送到客户端,客户端将其保存在一个隐藏域中,表单提交时将隐藏域一起提交,在服务器端 对token进行比较,如果相同,说明是一次提交,处理完成后将session中的token删除;如果不同,说明是重复提交. 以下是相关源代码:

令牌生成类:
package com.rcj.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import sun.misc.BASE64Encoder;

/**
 *
 * @author Mars
 * Time:2017年9月29日
 *
 */
public class TokenProccessor {

    //单例设计模式
    private TokenProccessor() {};
    private static TokenProccessor tp = new TokenProccessor();
    public static TokenProccessor getInstance() {
        return tp;
    }

    /**
     * 生成Token
     *
     */
    public String makeToken() {
        String token = (System.currentTimeMillis()+new Random().nextInt(999999999))+"";
        //数据指纹
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("md5");
            byte[] md5 = md.digest(token.getBytes());
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(md5);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

}
插入令牌servlet类
/**
 *
 * @author Mars
 * Time:2017年9月29日
 *
 */
public class FormServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String token = TokenProccessor.getInstance().makeToken();
        req.getSession().setAttribute("token", token);
        req.getRequestDispatcher("/resubmit.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(req, resp);
    }

}
form 表单:
<%--使用隐藏域存储生成的token--%>
    <form action = "doForm" id ="f" method = "post" >
        <input type = "text" style="display:none" name = "token" value = "${token}">
        <input type = "text" name= "username" autocomplete = "off"/>
        <input type = "submit" id = "submit" value="提交" onclick = "checkSubmit()">
    </form> 数据提交处理servlet类:package com.rcj.servlet;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 *
 * @author Mars
 * Time:2017年9月29日
 *
 */
public class DoFormServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        req.setCharacterEncoding("utf8");
        boolean b = isRepeatSubmit(req);
        if(b == true) {
            System.out.println("请不要重复提交");
            return ;
        }
        req.getSession().removeAttribute("token");
        String username = req.getParameter("username");
        System.out.println("数据库添加:"+username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(req, resp);
    }

    /**
     * 判断客户端提交上的令牌和服务器端是否一致
     * true  用户重复提交了表单
     * false 用户没有重复提交表单
     */
    private boolean isRepeatSubmit(HttpServletRequest  request) {

        try {
            String client_token = request.getParameter("token");
            if(client_token == null) {
                return true;
            }
            String server_token = request.getSession().getAttribute("token").toString();
            if(request.getSession().getAttribute("token").toString() == null) {
                return true;
            }
            if(!client_token.equals(server_token)) {
                return true;
            }
        } catch (Exception e) {
            return true;
        }
        return false;
    }
}
时间: 2024-11-11 06:38:28

表单重复提交--->使用Session防止表单重复提交的相关文章

JavaWeb学习总结(十三)——使用Session防止表单重复提交

在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提交的常见应用场景 有如下的form.jsp页面 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML>

10-客户端防表单重复提交和服务器端session防表单重复提交

/****************************************************DoFormServlet********************************************************/ package session; import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import

利用session防止表单重复提交

转自:http://www.cnblogs.com/xdp-gacl/p/3859416.html 利用Session防止表单重复提交 对于[场景二]和[场景三]导致表单重复提交的问题,既然客户端无法解决,那么就在服务器端解决,在服务器端解决就需要用到session了. 具体的做法:在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token.然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,

PHP+SESSION防止表单重复提交

index.php 当前表单页面is_submit设为0 SESSION_START(); $_SESSION['is_submit'] = 0; <form id="reg" action="post.php" method="post">     <p>用户名:<input type="text" class="input" name="username"

JavaWeb---总结(十三)使用Session防止表单重复提交

在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提交的常见应用场景 有如下的form.jsp页面 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML> <

[Java拾遗五]使用Session防止表单重复提交

申明:此文章属于转载, 转自博客: http://www.cnblogs.com/xdp-gacl/p/3859416.html在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提交的常见应用场景 有如下的form.jsp页面 1 <%@ page language="java" import="java.util.*&qu

使用Session防止表单重复提交

一.表单重复提交的常见应用场景 有如下的form.jsp页面 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML> 3 <html> 4 <head> 5 <title>Form表单</title> 6 </head> 7 8 <bod

JavaWeb之——使用Session防止表单重复提交(插曲)

  转载请注明出处:http://blog.csdn.net/l1028386804/article/details/45968185 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提交的场景 有如下的form.jsp页面 <%@ page language="java" import="java.util.*"

JavaWeb学习总结(一)——使用Session防止表单重复提交

在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提交的常见应用场景 有如下的form.jsp页面 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <!DOCTYPE HTML>