使用“提交”回调和 $.ajax 发布时多次提交的表单

Posted

技术标签:

【中文标题】使用“提交”回调和 $.ajax 发布时多次提交的表单【英文标题】:Form submitted multiple times when using the "submit" callback and $.ajax to post it 【发布时间】:2010-10-14 16:13:29 【问题描述】:

我一直在使用以下代码观察到一些奇怪的行为:

$.fn.submit_to_remote = function() 
  // I use .each instead of the .submit directly so I can save
  // the 'submitEnabled' variable separately for each form
  jQuery.each($(this), function() 
    $(this).submit(function() 
      form = $(this);
      if (form.data('submitEnabled') == false)  alert('disabled'); return false; 
      form.data('submitEnabled', false);
      $.ajax(type: 'POST', url: 'url', data: data, dataType: 'script',
        success: function(script) 
          alert('success')
        
      )
      return false;
    )
  )

$('.submit_to_remote').submit_to_remote();

因此,基本上,在表单上调用 submit_to_remote 时,它​​将禁用正常提交,然后发出 AJAX POST 请求。

奇怪的是表单被多次发布,因为“禁用”警报会显示。如您所见,我通过使用保存在表单对象上的“变量”来防止这种情况发生,并检查该变量以查看表单是否已提交。

经过进一步测试,罪魁祸首似乎是 AJAX 调用返回的脚本。让我解释一下我在做什么,这样会更清楚。

表单被发送到服务器,并返回一个脚本。该脚本再次显示表单,但这次显示某些字段的错误消息。请注意,表单已完全替换。

脚本在显示新表单后执行:

$('.submit_to_remote').submit_to_remote();

我必须这样做,否则,当您再次单击提交按钮时,表单会正常提交,没有 AJAX。

因此,假设用户提交表单并返回相应错误(未显示“禁用”警报)。然后他再次提交;这次“禁用”警报显示一次。现在他又提交了一次,这次警报显示了两次!等等……

所以看起来每次请求都会一次又一次地附加 .submit 回调,但为什么呢?

难道是通过使用 .html() 将原始表单保留为幽灵或其他东西?

谢谢!

PS:如果相关,这里是 $.ajax 调用返回的脚本:

replace_content_with = 'the form and other stuff here';
$('.page-content').html(replace_content_with);
$('.submit_to_remote').submit_to_remote();

【问题讨论】:

【参考方案1】:

是的,我同意 Seb,这是一个很好的做法,我认为在绑定之前始终取消绑定,除非您确定当前没有您想要的元素绑定。您可以通过简单地使用“.submit”、“.click”、“.mouseover”等功能来意外地双重绑定您的东西。

养成这样做的习惯(对我来说永远不会失败):

$('.some_element').unbind('submit').bind('submit',function() 
    // do stuff here...
);

...而不是:

$('.some_element').submit(function() 
    // do stuff here...
);

【讨论】:

我试试这个,但在我的情况下,有表单的提交,但如果我更新表单内容并重新提交,提交会发送原始内容。如果我不这样做,我将提交增量表单(1、2、3 等...)。 因为我重新绑定了提交“点击”按钮和“提交”操作,我的表单每次点击发送 4 次。讨厌的东西。完美的解决方案,但我很难量化我在寻找什么,从而找到了这个页面。 谢谢,拯救我的一天! ;)) 这是一个很好的解决方案。谢谢,您节省了我的时间。 这项工作对我来说非常棒,我会接受这个练习【参考方案2】:

解除绑定对我不起作用。这样做了:

$(document).off('submit');
$(document).on('submit',"#element_id",function(e)
    e.preventDefault();
    //do something
); 

希望对你有帮助……

其实 unbind() 如果在提交前进行一些验证和返回,可能会给你带来一些麻烦。示例:

$(document).on('submit',"#element_id",function(e)
    e.preventDefault();
    $(document).unbind('submit');
    var name = $(this).children('input[name="name"]').val();
    if( name == 'wrong name')
        return;

    //do something
);

在这种情况下,如果您输入的是“错误名称”,则不会提交表单,之后,当您输入“正确名称”时,不会触发 $(document).on('submit'.. , 既不是 e.preventDefault(); 也会以常规方式提交您的表单。

【讨论】:

谢谢 - 这正是我所需要的【参考方案3】:

不确定这种奇怪的行为,但似乎解除对提交事件的绑定可以解决问题。

因此,在运行 $.ajax 调用返回的脚本之前,请运行以下代码:

$('.submit_to_remote').unbind("submit");

这应该删除以前的绑定,只留下新的。

【讨论】:

我忘了说我也试过了,但奇怪的是它不起作用,因为新表单不会有 AJAX 行为,即使我用脚本重新绑定它。 .. +1 我可以在这里使用它作为解决方案:***.com/questions/12340484/…【参考方案4】:

更简单的是:

$(".some-class").off().submit(function() 
    //Do stuff here
);

【讨论】:

这是迄今为止最简单的修复方法【参考方案5】:

请记住,jQuery submit() 事件会查找: <input type="submit">, <input type="image">, or <button type="submit"> 形式为 (http://api.jquery.com/submit/)。一些框架默认 type 属性为“submit”,因此如果你试图覆盖默认值,请将 type 属性更改为其他内容,这样它就不会多次提交。

【讨论】:

【参考方案6】:

发生 OpenCart 双重提交是因为 common.js 中存在提交绑定。

通过对匹配"form-"的表单使用id模式来避免这种情况。

示例:<form id="myform" >

【讨论】:

【参考方案7】:

您可以使用此代码来解决:

$(this).submit(function() 
.
.
.
);

$(this).unbind("submit");

【讨论】:

【参考方案8】:

我遇到了同样的问题,并使用点击修复如下。

 $('.submit_to_remote').on('click', function()
//Some validation or other stuff
$(this).submit();
);

【讨论】:

以上是关于使用“提交”回调和 $.ajax 发布时多次提交的表单的主要内容,如果未能解决你的问题,请参考以下文章

使用 submit() 方法提交表单时的回调

Drupal 8表单提交Ajax表单后的回调

如何在提交按钮上多次单击时仅在数据库中插入一条记录

重力表单提交后的jQuery回调

$.ajax防止多次点击重复提交的方法

jquery ajax如何防止多次提交