表单重复提交解决方案

什么情况下会出现表单重复提交?

1、网络延迟

2、重新刷新

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

解决方案?

1、前端解决方案:让页面按钮只能点击一次或者将按钮设为点一次后就不可用(都不可靠,如果刷新还是会有重复提交)

修改form.jsp页面,添加如下的JavaScript代码来防止表单重复提交

代码:

<%@ 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) {
isFlag = true;
return true;
} else {
return false;
}
 
}
</script>
</head>
 
<body>
<form action="${pageContext.request.contextPath}/DoFormServlet"
method="post" οnsubmit="return submitFlag()">
用户名:<input type="text" name="userName"> <input type="submit"
value="提交" id="submit">
</form>
</body>
</html>

除了用这种方式之外,经常见的另一种方式就是表单提交之后,将提交按钮设置为不可用,让用户没有机会点击第二次提交按钮,代码如下:

function dosubmit(){
    //获取表单提交按钮
    var btnSubmit = document.getElementById("submit");
    //将表单提交按钮设置为不可用,这样就可以避免用户再次点击提交按钮
    btnSubmit.disabled= "disabled";
    //返回true让表单可以正常提交
    return true;
}
 

2、后端解决方案:使用Token(令牌)+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(HttpServletRequestreq, HttpServletResponseresp)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" οnsubmit="return dosubmit()">

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

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

</form>

</body>

</html>

 

后端java代码


@WebServlet("/DoFormServlet")

public class DoFormServlet extends HttpServlet {

@Override

protected void doPost(HttpServletRequestreq, HttpServletResponseresp)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 (Exceptione) {

// TODO: handle exception

}

System.out.println("往数据库插入数据...." +userName);

resp.getWriter().write("success");

}

 

public boolean isFlag(HttpServletRequestrequest) {

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;

}

}
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值