繁体   English   中英

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

[英]How can I prevent a double submit with jQuery or Javascript?

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

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

如何使用 javascript 或最好使用 jQuery 防止这些重复条目发生?

提前谢谢!

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

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

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

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

这应该可以解决问题:

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

没有 JQuery?

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

我见过的一种技术是为每个打开的表单分配一个唯一的 ID,并且每个表单只接受一个基于 ID 的提交。

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

我知道你要求一个 javascript 解决方案,但如果我需要健壮性,我个人会同时做这两个。

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

  • 按钮元素
  • 图片元素
  • 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;
});

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

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

我不确定您正在使用什么语言/框架,或者它是否只是纯 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..."} %>

这是我在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);
    });
});

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

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

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

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

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

如何防止页面刷新时重新提交表单 (F5 / CTRL+R) 中找到并解决问题:

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

这就是我为解决问题所做的。 我通过两次添加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);
        });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM