防止表单重复提交

记得之前做用户还款划扣的时候,由于没有做有效的防重复点击,导致多扣账户的情况,现在把常用的几种处理方式总结如下;

  1. 网络延迟,一次函数的调用没有返回的情况下,再次点击submit提交按钮
  2. 提交后点击【刷新】按钮导致表单重复提交
  3. 提交表单后点击浏览器后退按钮回到表单重新提交
解决方案一:在form表单代码中设置一个js标识位,第一次提交后将标志设置为true;如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<html>
<head>
<title></title>
<script type="text/javascript">
var isCommitted = false;//表单是否已经提交标识,默认为false
function dosubmit() {
if (isCommitted == false) {
isCommitted = true;//提交表单后,将表单是否已经提交标识设置为true
return true;//返回true让表单正常提交
} else {
return false;//返回false那么表单将不提交
}
}
</script>
</head>
<body>
<form action="/directcharge" onsubmit="return dosubmit()" method="post">
用户名:<input type="text" name="username">
<input type="submit" value="提交" id="submit">
</form>
</body>
</html>
解决方案二:第一次表单提交之后,将表单按钮设置不可用《disabled》
1
2
3
4
5
function dosubmit() {
var btnSubmit = document.getElementById("submit");
btnSubmit.disabled= "disabled";
return true;
}
解决方案三:利用Session防止表单重复提交
  1. php生成唯一sign,存储在Session以及表单隐藏域中;
  2. 第一次Submit对比客户端与服务器端Session值,如果不一致那就是重复提交,如果一致则提交表单,成功后Unset Session域中存储的Sign;
1
2
3
4
5
6
7
8
9
session_start();  
$sign = mt_rand(0, 1000000);
$_SESSION['sign'] = $sign;

<input type="hidden" name="sign" value="$sign"/>

if (!isset($_SESSION['sign']) || $_POST['sign'] != $_SESSION['sign']) {
die('error');
}
解决方案四:数据库添加唯一字段
  1. 数据库添加唯一约束或者创建唯一索引;
  2. 实现思路:对请求信息进行hash运算,得到一个hash值,则相同的请求得到相同的hash值;

    实现步骤:

    1. 接口A接收到请求之后,对请求信息hash运算,将hash值保存到数据库,对应列(column)满足unique约束,保存成功之后才能进行接下来的业务操作,比如提交订单,划扣等;
    2. 接口B接收到相同的请求,同样算出相同的hash值,当插入数据库时,由于column unique约束,所以保存失败;
  3. 隐患:程序中途挂了(网络超时,宕机…),后面重复提交,就无法成功了???

  4. 是否可以定时检测清理这个hash数据库表???
-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!