防止在jQuery中双重提交表单

我有一个表单需要一些时间来处理服务器。 我需要确保用户等待,而不是通过再次单击按钮尝试重新提交表单。 我尝试使用以下jQuery代码:

<script type="text/javascript"> $(document).ready(function() { $("form#my_form").submit(function() { $('input').attr('disabled', 'disabled'); $('a').attr('disabled', 'disabled'); return true; }); }); </script> 

当我在Firefox中试用这个功能时,所有的东西都被禁用了,但是表单并没有提交任何它应该包含的POST数据。 我不能使用jQuery来提交表单,因为我需要按钮与表单一起提交,因为有多个提交按钮,我确定哪个是哪个值被包含在POST中。 我需要通常提交的表单,并且在发生这种情况之后,我需要禁用所有的功能。

谢谢!

我认为你的问题是这样的:

 $('input').attr('disabled','disabled'); 

你正在禁用所有的输入,包括我猜想,那些表单应该提交的数据。

要禁用提交按钮,您可以这样做:

 $('button[type=submit], input[type=submit]').prop('disabled',true); 

但是,我不认为即使这些按钮被禁用,IE也会提交表单。 我会建议一个不同的方法。

一个jQuery插件来解决它

我们用下面的代码解决了这个问题。 这里的诀窍是使用jQuery的data()来标记已经提交或不提交的表单。 这样,我们就不必乱搞提交按钮,这吓坏了IE浏览器。

 // jQuery plugin to prevent double submission of forms jQuery.fn.preventDoubleSubmission = function() { $(this).on('submit',function(e){ var $form = $(this); if ($form.data('submitted') === true) { // Previously submitted - don't submit again e.preventDefault(); } else { // Mark it so that the next submit can be ignored $form.data('submitted', true); } }); // Keep chainability return this; }; 

像这样使用它:

 $('form').preventDoubleSubmission(); 

如果有AJAX表单应该被允许提交每页加载多次,你可以给他们一个类,指示,然后排除他们像你这样的选择:

 $('form:not(.js-allow-double-submission)').preventDoubleSubmission(); 

定时方法是错误的 – 你怎么知道这个动作会在客户端的浏览器上运行多长时间?

怎么做

 $('form').submit(function(){ $(this).find(':submit').attr('disabled','disabled'); }); 

当提交表单时,将会禁用里面的所有提交按钮。

记住,在Firefox中,当你禁用一个按钮时,当你回到历史中时,这个状态将被记住。 例如,要防止在页面加载时启用按钮。

我觉得Nathan Long的答案是要走的路。 对我来说,我正在使用客户端验证,所以我只是添加了一个条件,表单是有效的。

编辑 :如果没有添加,如果客户端验证遇到错误,用户将永远不能提交表单。

  // jQuery plugin to prevent double submission of forms jQuery.fn.preventDoubleSubmission = function () { $(this).on('submit', function (e) { var $form = $(this); if ($form.data('submitted') === true) { // Previously submitted - don't submit again alert('Form already submitted. Please wait.'); e.preventDefault(); } else { // Mark it so that the next submit can be ignored // ADDED requirement that form be valid if($form.valid()) { $form.data('submitted', true); } } }); // Keep chainability return this; }; 

请检查jquery-safeform插件。

用法示例:

 $('.safeform').safeform({ timeout: 5000, // disable next submission for 5 sec submit: function() { // You can put validation and ajax stuff here... // When done no need to wait for timeout, re-enable the form ASAP $(this).safeform('complete'); return false; } }); 

event.timeStamp在Firefox中不起作用。 返回false是非标准的,你应该调用event.preventDefault() 。 而我们在这个时候, 总是使用花括号来控制结构 。

总结所有以前的答案,这里是一个插件,做的工作和跨浏览器的作品。

 jQuery.fn.preventDoubleSubmission = function() { var last_clicked, time_since_clicked; jQuery(this).bind('submit', function(event) { if(last_clicked) { time_since_clicked = jQuery.now() - last_clicked; } last_clicked = jQuery.now(); if(time_since_clicked < 2000) { // Blocking form submit because it was too soon after the last submit. event.preventDefault(); } return true; }); }; 

为了解决Kern31问题,计时方法适用于我,只是因为我们试图停止双击提交按钮。 如果您对提交的回复时间非常长,我建议您使用微调来替换提交按钮或表单。

完全封锁表格的后续提交,就像上面的大多数例子一样,有一个不好的副作用:如果网络发生故障,他们想要重新提交,他们将无法做到这一点,将失去他们的变化制作。 这肯定会让一个愤怒的用户。

…但表单没有提交任何POST数据,它应该包括在内。

正确。 禁用的表单元素名称/值将不会发送到服务器。 你应该把它们设置为只读元素。

而且,锚不能像这样被禁用。 您将需要删除他们的HREF(不推荐)或防止他们的默认行为(更好的方式),例如:

 <script type="text/javascript"> $(document).ready(function(){ $("form#my_form").submit(function(){ $('input').attr('readonly', true); $('input[type=submit]').attr("disabled", "disabled"); $('a').unbind("click").click(function(e) { e.preventDefault(); // or return false; }); }); </script> 

有可能改善Nathan Long的方法 。 你可以用这个替换已经提交的表单的检测逻辑:

 var lastTime = $(this).data("lastSubmitTime"); if (lastTime && typeof lastTime === "object") { var now = new Date(); if ((now - lastTime) > 2000) // 2000ms return true; else return false; } $(this).data("lastSubmitTime", new Date()); return true; // or do an ajax call or smth else 

Nathan的代码,但为jQuery验证插件

如果你碰巧使用jQuery Validate插件,他们已经提交了处理程序,在这种情况下,没有理由实现多个。 代码:

 jQuery.validator.setDefaults({ submitHandler: function(form){ // Prevent double submit if($(form).data('submitted')===true){ // Previously submitted - don't submit again return false; } else { // Mark form as 'submitted' so that the next submit can be ignored $(form).data('submitted', true); return true; } } }); 

你可以很容易地在} else { -block内扩展它以禁用输入和/或提交按钮。

干杯

如果使用AJAX发布表单,设置async: false应该防止在表单清除之前进行额外的提交:

 $("#form").submit(function(){ var one = $("#one").val(); var two = $("#two").val(); $.ajax({ type: "POST", async: false, // <------ Will complete submit before allowing further action url: "process.php", data: "one="+one+"&two="+two+"&add=true", success: function(result){ console.log(result); // do something with result }, error: function(){alert('Error!')} }); return false; } }); 

对于Bootstrap 3,修改了Nathan的解决方案。这会将加载文本设置为提交按钮。 此外,它将在30秒后超时,并允许表单重新提交。

 jQuery.fn.preventDoubleSubmission = function() { $('input[type="submit"]').data('loading-text', 'Loading...'); $(this).on('submit',function(e){ var $form = $(this); $('input[type="submit"]', $form).button('loading'); if ($form.data('submitted') === true) { // Previously submitted - don't submit again e.preventDefault(); } else { // Mark it so that the next submit can be ignored $form.data('submitted', true); $form.setFormTimeout(); } }); // Keep chainability return this; }; jQuery.fn.setFormTimeout = function() { var $form = $(this); setTimeout(function() { $('input[type="submit"]', $form).button('reset'); alert('Form failed to submit within 30 seconds'); }, 30000); }; 

我最终使用这个帖子的想法来提出一个与AtZako版本非常相似的解决方案。

  jQuery.fn.preventDoubleSubmission = function() { var last_clicked, time_since_clicked; $(this).bind('submit', function(event){ if(last_clicked) time_since_clicked = event.timeStamp - last_clicked; last_clicked = event.timeStamp; if(time_since_clicked < 2000) return false; return true; }); }; 

像这样使用:

 $('#my-form').preventDoubleSubmission(); 

我发现解决方案中没有包含某种类型的超时,但只是禁用了提交或禁用的表单元素,因为一旦锁定被触发,您将无法再次提交,直到刷新页面。 这在我做一些Ajax的时候会导致一些问题。

这可能可能有点小,因为它不那么花哨。

使用两个提交按钮。

 <input id="sub" name="sub" type="submit" value="OK, Save"> <input id="sub2" name="sub2" type="submit" value="Hidden Submit" style="display:none"> 

和jQuery:

 $("#sub").click(function(){ $(this).val("Please wait.."); $(this).attr("disabled","disabled"); $("#sub2").click(); }); 

我一直有类似的问题,我的解决方案如下。

如果您没有任何客户端验证,那么您可以简单地使用这里记录的jquery one()方法。

http://api.jquery.com/one/

这被调用后禁用处理程序。

 $("#mysavebuttonid").on("click", function () { $('form').submit(); }); 

如果你正在做客户端验证,那么它稍微有些棘手。 上面的例子不会让你验证失败后再次提交。 试试这个方法

 $("#mysavebuttonid").on("click", function (event) { $('form').submit(); if (boolFormPassedClientSideValidation) { //form has passed client side validation and is going to be saved //now disable this button from future presses $(this).off(event); } }); 

这里是我如何做到这一点:

 $(document).ready(function () { $('.class_name').click(function () { $(this).parent().append('<img src="data:image/gif;base64,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" />'); $(this).hide(); }); }); 

学分: https : //github.com/phpawy/jquery-submit-once

这个代码会在按钮标签上显示加载,并将按钮设置为

禁用状态,然后处理后,重新启用并返回原来的按钮文本**

 $(function () { $(".btn-Loading").each(function (idx, elm) { $(elm).click(function () { //do processing if ($(".input-validation-error").length > 0) return; $(this).attr("label", $(this).text()).text("loading ...."); $(this).delay(1000).animate({ disabled: true }, 1000, function () { //original event call $.when($(elm).delay(1000).one("click")).done(function () { $(this).animate({ disabled: false }, 1000, function () { $(this).text($(this).attr("label")); }) }); //processing finalized }); }); }); // and fire it after definition } 

);

我的解决方案

 // jQuery plugin to prevent double submission of forms $.fn.preventDoubleSubmission = function () { var $form = $(this); $form.find('[type="submit"]').click(function () { $(this).prop('disabled', true); $form.submit(); }); // Keep chainability return this; }; 

在我的情况下,表单的onsubmit有一些验证码,所以我增加了Nathan Long的回答,包括一个onsubmit检查点

 $.fn.preventDoubleSubmission = function() { $(this).on('submit',function(e){ var $form = $(this); //if the form has something in onsubmit var submitCode = $form.attr('onsubmit'); if(submitCode != undefined && submitCode != ''){ var submitFunction = new Function (submitCode); if(!submitFunction()){ event.preventDefault(); return false; } } if ($form.data('submitted') === true) { /*Previously submitted - don't submit again */ e.preventDefault(); } else { /*Mark it so that the next submit can be ignored*/ $form.data('submitted', true); } }); /*Keep chainability*/ return this; }; 

我解决了一个非常类似的问题:

 $("#my_form").submit(function(){ $('input[type=submit]').click(function(event){ event.preventDefault(); }); }); 
Interesting Posts