如何防止用户重复提交表单

21
<input type="submit" name="btnADD" id="btnADD" value="ADD"/>

当用户点击两次添加按钮时,会导致相同的数据被提交两次到表格中。因此,请帮助我限制用户只能提交一次。


一般来说,您可以添加一些数据库限制或其他内容,以确保在任何情况下都不会发生错误。 - quazar
16个回答

33
提交表单后,使用jQuery附加一个处理程序,劫持并“禁用”提交处理程序。
var $myForm = $("#my_form");
$myForm.submit(function(){
    $myForm.submit(function(){
        return false;
    });
});

如果从提交处理程序返回"false",则会阻止表单提交。禁用按钮可能会对表单的处理方式产生奇怪的影响。这种方法似乎基本上没有副作用,即使在具有多个提交按钮的表单上也可以使用。


1
似乎这是最好的解决方案,因为如果在提交之前禁用提交按钮,您将无法验证提交按钮的值,因为它不会被发送... - Axi
1
非常好。为了方便使用,让这个处理程序也改变按钮的外观(禁用或以其他方式向用户清楚地表明“计算机现在会说不,请等一下…”)可能是个好主意。 - st3inn
2
这个小问题是每次用户点击按钮时,都会添加另一个事件处理程序。这不会引起任何问题,但有些人可能不想要这样。一个简单的解决方法是在添加新的处理程序之前,简单地删除表单上的任何“提交”处理程序。 - Hayley
1
它能够工作,但是如果验证失败并且表单没有被提交,它也会禁用按钮 - 在我的情况下是这样的。 - Toadfish
1
很好的回答,但请告诉我们禁用提交按钮会有什么奇怪的副作用? - ADTC
显示剩余5条评论

26

尝试一下这段代码...

<input type="submit" name="btnADD" id="btnADD" value="ADD" onclick="this.disabled=true;this.value='Sending, please wait...';this.form.submit();" />

9
如果用户在一个字段上按回车键,这样做不会提交表单吗? - Ziyan Junaideen
用户也可以通过浏览器(检查元素)编辑代码来重新启用按钮。 - foxt7ot
1
如果输入不正确怎么办?比如用户在数字输入中输入了一个小于0的值,而属性min=0。按钮将被禁用,用户在纠正输入后将无法重新点击它,对吗? - pawamoy
4
如果用户很精通,无论你采取什么JavaScript措施来防止其双重发布,他都会找到方法。只有服务器端的重复检查才能真正防止它。 - ADTC
解决了问题,救了我一命! - undefined
显示剩余2条评论

7

您可以在点击后禁用按钮或将其隐藏。

<input type="submit" name="btnADD" id="btnADD" value="ADD" onclick="disableButton(this)"/>

js :

 function disableButton(button) {
     button.disabled = true;
     button.value = "submitting...."
     button.form.submit();
}

4
如果你正在使用Java服务器端脚本,并且同时使用Struts 2,那么可以参考这个链接,它介绍了如何使用令牌。

http://www.xinotes.org/notes/note/369/

应该生成一个令牌并将其保存在会话中以进行初始页面呈现。当首次提交请求时,一起提交令牌,在Struts操作中运行一个线程,线程名为令牌ID并运行客户端请求的逻辑。当客户端再次提交相同的请求时,检查线程是否仍在运行(thread.getcurrentthread().interrupted),如果仍在运行,则发送客户端重定向503。

如果您没有使用任何框架,并且正在寻找简单的解决方案。 您可以借助下面的内容

java.util.UUID.randomUUID();

只需将随机uuid放入会话,并放入隐藏的表单字段中,在另一端(处理其他工作,如将数据存储到数据库等的jsp页面)中从会话和隐藏的表单字段中取出uuid。如果表单字段匹配,则继续进行,从会话中删除uuid;否则,可能是表单已被重新提交。
为了帮助您,我写了一些代码片段来给您一个实现的思路。
<%
String formId=(java.util.UUID.randomUUID()).toString();
session.setAttribute(formId,formId);
%>
<input type='hidden' id='formId' name='formId' value='<%=formId%>'>

您分享的链接,如果我使用这种方法,第二个请求可能会被处理,而第一个请求则被取消。我是对的吗? - Sunny Gupta

3
您可以提醒用户喝咖啡过多,但最好的方法是使用JavaScript禁用按钮,例如:
$("#btnADD").on('click', function(btn) {
  btn.disabled = true;
});

哈哈,我刚遇到了这个问题,有人提交了同一个表单11次!经过测试,发现他们手指非常灵活。这又让我来到了这里... :D - Chud37

2
我根据rogueleaderr的答案制定了一种解决方案:
jQuery('form').submit(function(){
    jQuery(this).unbind('submit'); // unbind this submit handler first and ...
    jQuery(this).submit(function(){ // added the new submit handler (that does nothing)
        return false;
    });
    console.log('submitting form'); // only for testing purposes
});

2

我对类似问题的解决方案是创建一个单独的、隐藏的提交按钮。它的工作方式如下:

  • 您单击第一个可见按钮。
  • 第一个按钮被禁用。
  • onclick 导致第二个提交按钮被按下。
  • 表单被提交。
<input type="submit" value="Email" onclick="this.disabled=true; this.value='Emailing...'; document.getElementById('submit-button').click();">
<input type="submit" id='submit-button' value="Email" name="btnSubmitSendCertificate" style='display:none;'>

我选择这种方式只是为了让其他在代码上工作的人更加清晰易懂。还有其他可能更加主观优秀的解决方案。


1

在提交表单时添加一个类,以防止用户双击/重复提交

$('form[method=post]').each(function(){
   $(this).submit(function(form_submission) {
     if($(form_submission.target).attr('data-submitted')){
        form_submission.preventDefault();
     }else{
        $(form_submission.target).attr('data-submitted', true);
     }
  });
});

1
当用户点击提交按钮时,禁用该按钮。
<form onSubmit="disable()"></form>

function disable()
{
     document.getElementById('submitBtn').disabled = true;
    //SUBMIT HERE
}

+1 写完整的代�并制作一个 jsFiddle 是个好主�,😉。 - user1823761
1
我一直在使用这种技术,但最近遇到了一个问题。禁用的输入框不会被发送到服务器,当我更改服务器脚本以测试 $_POST['submitBtn'](因为我添加了多个提交按钮并需要知道它们使用的是哪一个)时,它失败了,因为它没有被设置。 - Barmar
@Barmar 你可以隐藏按钮或者(如果你需要保持按钮可见),在按钮上方放置一个 div,这样它就无法被点击。这样按钮就不会被禁用,并且将随表单数据一起发送。 - ADTC
仅仅在表单上禁用按钮是不够的,这会阻止表单被提交。 - Kevin D.

1
禁用提交按钮。
$('#btnADD').attr('disabled','disabled');

      or

$('#btnADD').attr('disabled','true');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接