防止在jQuery中重复提交表单

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

I have a form that takes a little while for the server to process. I need to ensure that the user waits and does not attempt to resubmit the form by clicking the button again. I tried using the following jQuery code:

<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 中.我需要像往常一样提交表单,并且在发生这种情况后我需要立即禁用所有内容.

When I try this in Firefox everything gets disabled but the form is not submitted with any of the POST data it is supposed to include. I can't use jQuery to submit the form because I need the button to be submitted with the form as there are multiple submit buttons and I determine which was used by which one's value is included in the POST. I need the form to be submitted as it usually is and I need to disable everything right after that happens.

谢谢!

推荐答案

2018 年更新:我刚刚为这个旧答案得到了一些分数,只是想补充一下 best 解决方案是使操作具有幂等性,以便重复提交是无害的.

Update in 2018: I just got some points for this old answer, and just wanted to add that the best solution would be to make the operation idempotent so that duplicate submissions are harmless.

例如,如果表单创建订单,则在表单中放置一个唯一 ID.服务器第一次看到具有该 ID 的订单创建请求时,它应该创建它并响应成功".随后的提交也应回复成功".(如果客户没有得到第一个响应)但不应该改变任何东西.

Eg, if the form creates an order, put a unique ID in the form. The first time the server sees an order creation request with that id, it should create it and respond "success". Subsequent submissions should also respond "success" (in case the client didn't get the first response) but shouldn't change anything.

应通过数据库中的唯一性检查来检测重复项,以防止出现竞争条件.

Duplicates should be detected via a uniqueness check in the database to prevent race conditions.

我认为你的问题是这一行:

I think that your problem is this line:

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

您正在禁用所有输入,包括我猜想表单应该提交其数据的输入.

You're disabling ALL the inputs, including, I'd guess, the ones whose data the form is supposed to submit.

要仅禁用提交按钮,您可以执行以下操作:

To disable just the submit button(s), you could do this:

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

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

However, I don't think IE will submit the form if even those buttons are disabled. I'd suggest a different approach.

我们刚刚用下面的代码解决了这个问题.这里的技巧是使用 jQuery 的 data() 来标记表单是否已经提交.这样一来,我们就不必弄乱提交按钮,这会让 IE 崩溃.

We just solved this problem with the following code. The trick here is using jQuery's data() to mark the form as already submitted or not. That way, we don't have to mess with the submit buttons, which freaks IE out.

// 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 表单应该允许在每次页面加载时提交多次,您可以给它们一个类来指示,然后将它们从选择器中排除,如下所示:

If there are AJAX forms that should be allowed to submit multiple times per page load, you can give them a class indicating that, then exclude them from your selector like this:

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

相关文章