如何防止使用 jQuery 或 Javascript 进行双重提交?

Posted

技术标签:

【中文标题】如何防止使用 jQuery 或 Javascript 进行双重提交?【英文标题】:How can I prevent a double submit with jQuery or Javascript? 【发布时间】:2011-02-07 19:17:13 【问题描述】:

由于不耐烦的用户多次单击提交按钮,我的数据库中不断出现重复条目​​。

我用谷歌搜索和搜索,找到了一些脚本,但似乎都不够。

如何使用 javascript 或者最好是 jQuery 来防止这些重复条目的出现?

提前谢谢!

【问题讨论】:

【参考方案1】:

如何禁用提交按钮?我就是做这个的。它工作正常。

$('form').submit(function()
    $('input[type=submit]', this).attr('disabled', 'disabled');
);

免责声明: 这仅在用户浏览器上启用 javascript 时有效。如果提交的数据很重要(比如信用卡购买),那么将我的解决方案视为第一道防线。但是对于许多用例,禁用提交按钮将提供足够的预防。

我会先实现这个仅限 javascript 的解决方案。然后跟踪仍有多少重复记录被创建。如果它为零(或低到不关心),那么你就完成了。如果它对您来说太高,那么对现有记录实施后端数据库检查。

【讨论】:

Javascript 只是这里解决方案的一部分,您还应该检查数据库以检查是否刚刚输入了数据。如果您有一条独特的数据,您可以检查这是最好的方法,但另一种方法是在数据上设置时间戳并检查该用户是否在短时间内添加了任何内容。但是,这将取决于您要添加的应用程序。 我确实有一个可以检查的唯一数据,每个 id_number 都是唯一的,我将如何实施这样的检查? @kielie id_number 是一个身份字段吗? 不,不是,这是用户输入的正常字段,但每个字段都是唯一的。 如果表单值很重要,则解决方案不好。只有未禁用的字段才会被发送。禁用的字段(按钮)不会与表单一起发送。在这种情况下,使用这个变体 ` var isFormSubmitted = false; form.submit(function() if(isFormSubmitted) return false; //如果表单有效禁用提交表单以防止重复提交 isFormSubmitted = true; ); `【参考方案2】:

这应该可以解决问题:

$("form").submit(function() 
   $(":submit", this).attr("disabled", "disabled");
);

没有 JQuery?

或者,您可以从 db 进行检查以检查记录是否已存在,如果存在,则不要插入新记录。

【讨论】:

我确实有一个可以检查的唯一数据,每个 id_number 都是唯一的,我将如何实施这样的检查?【参考方案3】:

我见过使用的一种技术是为每个打开的表单分配一个唯一的 ID,并根据 ID 只接受每个表单的一次提交。

这也意味着您可以检查人们根本不费心提交的次数,并且您可以检查提交是否真正来自您的表单,方法是检查它是否具有您的服务器创建的 ID。

我知道您要求使用 javascript 解决方案,但如果我需要稳健性,我个人会同时做这两个。

【讨论】:

对于涉及资金转移的关键任务应用程序,这确实是最好的方法。【参考方案4】:

防止重复发布并不像禁用提交按钮那么简单。还有其他元素可以提交:

按钮元素 img 元素 javascripts 在某些文本字段上按“输入”

使用 jQuery 数据容器将是我的选择。这是一个例子:

$('#someForm').submit(function()
    $this = $(this);

    /** prevent double posting */
    if ($this.data().isSubmitted) 
        return false;
    

    /** do some processing */

    /** mark the form as processed, so we will not process it again */
    $this.data().isSubmitted = true;

    return true;
);

【讨论】:

【参考方案5】:

这是我用来避免双击问题的一些 jQuery。它只允许单击提交按钮。

$(document).ready(function() 
  $("#submit").on('click', function() 
  );
);

【讨论】:

这很好,但是如果表单中的某种验证失败,那么表单必须重新加载,对吧?【参考方案6】:

我不确定您使用的是什么语言/框架,或者它是否只是纯 html。但是在我编写的 Rails 应用程序中,我在表单按钮 disable_with 上传递了一个数据属性,该属性可防止在事务处理过程中多次单击该按钮。

这是 ERB 的样子。

<%= f.button "Log In", class: 'btn btn-large btn-block btn-primary', data: disable_with: "<i class='icon-spinner'></i>Logging In..." %>

【讨论】:

【参考方案7】:

这是我在https://github.com/liberapay/liberapay.com/pull/875 中想到的:

$('form').on('submit', function (e) 
    var $form = $(this);
    // Check that the form hasn't already been submitted
    if ($form.data('js-submit-disable')) 
        e.preventDefault();
        return false;
    
    // Prevent submitting again
    $form.data('js-submit-disable', true);
    // Set a timer to disable inputs for visual feedback
    var $inputs = $form.find(':not(:disabled)');
    setTimeout(function ()  $inputs.prop('disabled', true); , 100);
    // Unlock if the user comes back to the page
    $(window).on('focus pageshow', function () 
        $form.data('js-submit-disable', false);
        $inputs.prop('disabled', false);
    );
);

【讨论】:

【参考方案8】:

here 描述的方法的问题是,如果您使用的是 javascript 验证框架并且验证失败,您将无法在不刷新页面的情况下更正并重新提交表单。

要解决这个问题,您需要插入验证框架的成功事件,然后才将提交控件设置为禁用。使用Parsley,您可以使用以下代码插入表单验证事件:

$.listen('parsley:form:validated', function(e)
    if (e.validationResult) 
        /* Validation has passed, prevent double form submissions */
        $('button[type=submit]').attr('disabled', 'disabled');
  
);

【讨论】:

【参考方案9】:

如果您正在使用客户端验证,并且希望在数据无效时允许额外的提交尝试,您可以仅在表单内容未更改时才允许提交:

var submittedFormContent = null;
$('#myForm').submit(function (e) 
    var newFormContent = $(this).serialize();
    if (submittedFormContent === newFormContent)
        e.preventDefault(true);
    else 
        submittedFormContent = newFormContent;
);

【讨论】:

【参考方案10】:

在How to prevent form resubmission when page is refreshed (F5 / CTRL+R)找到并解决了问题:

    <script>
        if ( window.history.replaceState ) 
            window.history.replaceState( null, null, window.location.href );
        
    </script>

【讨论】:

【参考方案11】:

这就是我为解决问题所做的。 我通过添加 setTimeout 两次禁用了该按钮: -第一次是让JS表单字段验证工作;-第二次是启用按钮以防万一在您的后端进行任何验证,这可能会返回错误,因此用户将希望在编辑他的数据后再次尝试提交表单。

$(document).ready(function()
        $('button[type=submit]').on("click", function()
            setTimeout(function () 
                $('button[type=submit]').prop('disabled', true);
                , 0);
            setTimeout(function () 
                $('button[type=submit]').prop('disabled', false);
                , 1000);
        );
);

【讨论】:

使用定时器不好。如果承诺需要很长时间才能完成怎么办?

以上是关于如何防止使用 jQuery 或 Javascript 进行双重提交?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JavaScript 或 jQuery 更改数组内的对象的值?

当用户点击地址栏输入使用 JQuery 或 JS 时,如何防止网页重新加载

防止用户使用 jquery 或 javascript 重新加载页面 [重复]

在将按钮添加到 jQuery UI 对话框时,如何防止有人更改或避免我的 JavaScript 逻辑?

如何防止滚动使用jquery跳过列表中的项目?

javascrip jquery 学习随笔