您的位置:首页 > 其它

web开发之防止表单重复提交

2017-11-05 20:49 274 查看

表单重复提交的模拟场景

1、网络延时

 在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。

2.重新刷新

表单提交后用户点击【刷新】按钮导致表单重复提交

3.点击浏览器的【后退】按钮回退到表单页面后进行再次提交

用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交

表单重复提交的解决方案

1. 使用javascript 解决


[b]<%@ 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>
<title>Form表单</title>
<script
type="text/javascript">
    var isFlag =
false; //表单是否已经提交标识,默认为false
 

    function submitFlag() {

 

        if (isFlag ==
false) {

            isFlag= true;

            return
true;

        }else {

            return
false;

        }

 

    }
</script>
</head>
 
<body>
    <form
action="${pageContext.request.contextPath}/DoFormServlet"
        method="post"
onsubmit="returnsubmitFlag()">
        用户名:<input
type="text"name="userName">
<input
type="submit"
            value="提交"
id="submit">
    </form>
</body>
</html>
[/b]
 对于【场景二】和【场景三】导致表单重复提交的问题,既然客户端无法解决,那么就在服务器端解决,在服务器端解决就需要用到session了。

  具体的做法:在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token。然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端,然后在服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。

  在下列情况下,服务器程序将拒绝处理用户提交的表单请求:

1.    存储Session域中的Token(令牌)与表单提交的Token(令牌)不同。
2.    当前用户的Session中不存在Token(令牌)。
3.    用户提交的表单数据中没有Token(令牌)。


@WebServlet("/ForwardServlet")
public
class ForwardServlet extends HttpServlet {

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

       req.getSession().setAttribute("sesionToken", TokenUtils.getToken());
       req.getRequestDispatcher("form.jsp").forward(req,
resp);

    }
}


<%@
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>
<title>Form表单</title>
 
</head>
 
<body>
    <form
action="${pageContext.request.contextPath}/DoFormServlet"

        method="post"
onsubmit="return dosubmit()">

        <input
type="hidden"
name="token"
value="${sesionToken}"> 用户名:<input
type="text"

            name="userName">
<input
type="submit"
value="提交"
id="submit">

    </form>
</body>
</html>

@WebServlet("/DoFormServlet")
public
class
DoFormServlet extends HttpServlet {
    @Override
    protected
void
doPost(HttpServletRequest req, HttpServletResponse
resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        boolean
flag = isFlag(req);
        if (!flag) {
            resp.getWriter().write("已经提交...");
            System.out.println("数据已经提交了..");
            return;
        }
        String userName =
req.getParameter("userName");
        try {
            Thread.sleep(300);
        } catch (Exception
e) {
            // TODO: handle exception
        }
        System.out.println("往数据库插入数据...." +
userName);
        resp.getWriter().write("success");
    }
 
    public
boolean
isFlag(HttpServletRequest request) {
        HttpSession session =
request.getSession();
        String sesionToken = (String)
session.getAttribute("sesionToken");
        String token =
request.getParameter("token");
        if (!(token.equals(sesionToken))) {
            return
false
;
        }
        session.removeAttribute("sesionToken");
        return
true
;
    }
}
 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: