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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/668314/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 09:33:08  来源:igfitidea点击:

Form submitted multiple times when using the "submit" callback and $.ajax to post it

jqueryajaxforms

提问by Ivan

I've been observing some strange behavior with the following code:

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

$.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();

So, basically, upon calling submit_to_remote on a form(s), it will disable it's normal submit and then make an AJAX POST request.

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

The strange thing is that the form gets posted multiple times, as the 'disabled' alert will show. As you can see, I'm preventing this by using a "variable" saved on the form object, and checking that variable to see if the form has already been submitted.

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

Upon further testing, it seems that the culprit is the script returned by the AJAX call. Let me explain a bit what I'm doing so it's more clear.

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

The form gets posted to the server, and a script returned. The script shows the form again, but this time with error messages for some fields. Note that the form is completely replaced.

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

The script, upon showing the new form, executes this:

该脚本在显示新表单时执行以下操作:

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

I have to do that because otherwise, when you click on the submit button again, the form is submitted normally, no AJAX.

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

So, say a user submits the form and it's returned back with the appropriate errors (the 'disabled' alert is not shown). Then he submits it again; this time the 'disabled' alert is shown once. Now he submits it one more time, and this time the alert is shown twice! And so on...

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

So it would seem that the .submit callback is being appended again and again with each request, but why?

因此,似乎每次请求都会一次又一次地附加 .submit 回调,但为什么呢?

Could it be that by using .html() the original form is kept as a ghost or something?

可能是通过使用 .html() 将原始表单保留为幽灵还是什么?

Thanks!

谢谢!

PS: In case it's relevant, here's the script returned by the $.ajax call:

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

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

回答by KyleFarris

Yes, I agree with Seb, it's a good practice, in my opinion to always unbind before binding unless you are certain that there aren't currently binds to your element that you want. You can double bind your stuff on accident by simply using the '.submit', '.click', '.mouseover', etc... functions.

是的,我同意 Seb,这是一个很好的做法,在我看来,除非您确定当前没有绑定到您想要的元素,否则总是在绑定之前解除绑定。您可以通过简单地使用“.submit”、“.click”、“.mouseover”等...函数来意外地双重绑定您的东西。

Get into the habit of doing this (never fails for me):

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

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

... instead of:

... 代替:

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

回答by Iliya Kolev

Unbind didn't work for me. This did:

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

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

I hope it helps...

我希望它有帮助...

In fact unbind() can bring you some troubles if you have some validation and return before submit. Example:

实际上,如果您在提交之前进行一些验证和返回,则 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
});

In this case if you input is 'wrong name' the form will not be submitted and after that, when you put the "right name", the $(document).on('submit'.. will not be triggered, neither the e.preventDefault(); and your form will be submitted in the regular way .

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

回答by Seb

Not sure about this strange behavior, but seems that unbinding the submit event will do the trick.

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

So, before running the script returned by the $.ajax call, run this:

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

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

That should remove previous bindings and leave just the new one.

那应该删除以前的绑定并只留下新的绑定。

回答by shell

Easier yet is:

更简单的是:

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

回答by fahad

Keep in mind that the jQuery submit() event looks for: <input type="submit">, <input type="image">, or <button type="submit">in the form (http://api.jquery.com/submit/). Some frameworks default the type attribute to "submit", so if you are trying to override the default, change the type attribute to something else so it doesn't submit multiple times.

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

回答by George-Paul B.

OpenCart double submit happens because there is a submit bind in common.js.

OpenCart 双重提交发生是因为common.js.

Avoid this by using an id pattern for the form that does notmatch "form-".

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

Example: <form id="myform" >.

例子:<form id="myform" >

回答by HamidReza

you can use this code to resolve :

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

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

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

回答by Jaison

I had the same problem and fixed like below using click.

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

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