防止 "double submit" 形式的 Ajax 问题

Preventing the "double submit" problem in Ajax form

我有网站联系表格,提交后有时需要几秒钟才能发送。

用户,通常是因为不耐烦,再次点击。这导致表单被多次发送到主机。

为了防止这种情况,我尝试按照这些思路实施一些方法,但认为有一些更清洁更好的方法:

$.fn.click1 = function(fn) {  
  $(this).data('clicked', false);  
  $(this).click(function(o) {  
    if ($(this).data('clicked')) return false;  
    $(this).data('clicked', true);  
    fn(o);  
    return false;  
  });  
};  

$(function() {

  // get the form
  var form = $('#modal-contact-form');

  // get the messages element
  var formMessages = $('#modal-contact-form-responses');

  // set up event listener for contact form
  $(form).submit(function(e) {
    // disable html submit button
    e.preventDefault();

    // serialize form data
    var formData = $(form).serialize();

    // submit form using AJAX
    $.ajax({
        type: 'POST',
        url: $(form).attr('action'),
        data: formData
      })
      .done(function(response) {
        // make sure formMessages element has 'success' class
        $(formMessages).removeClass('error');
        $(formMessages).addClass('success');

        // set message text
        $(formMessages).text('Your message has been sent. Thank you!');

        // clear form
        $('input, textarea').val('');
        $("#modal-contact-form-message").trigger('change');
      })
      .fail(function(data) {
        // make sure formMessages element has 'error' class
        $(formMessages).removeClass('success');
        $(formMessages).addClass('error');

        // set the message text
        $(formMessages).text('Input error. Please review and re-submit.');
      });

  });

});

// text area character counter
// disables submit button when < 0
(function($) {

  $.fn.charCount = function(submit, options) {

    this.submit = submit;

    // default configuration properties
    var defaults = {
      allowed: 1250,
      warning: 150,
      css: 'counter',
      counterElement: 'span',
      cssWarning: 'warning',
      cssExceeded: 'exceeded',
      counterText: ''
    };

    var options = $.extend(defaults, options);

    function calculate(obj, submit) {

      submit.attr("disabled", "disabled");

      var count = $(obj).val().length;
      var available = options.allowed - count;
      if (available <= options.warning && available >= 0) {
        $(obj).next().addClass(options.cssWarning);
      } else {
        $(obj).next().removeClass(options.cssWarning);
      }
      if (available < 0) {
        $(obj).next().addClass(options.cssExceeded);
      } else {
        $(obj).next().removeClass(options.cssExceeded);
        submit.removeAttr("disabled");
      }

      $(obj).next().html(options.counterText + available);
    };

    this.each(function() {
      $(this).after('<' + options.counterElement + ' class="' + options.css + '">' + options.counterText + '</' + options.counterElement + '>');

      calculate(this, submit);

      $(this).keyup(function() {
        calculate(this, submit)
      });
      $(this).change(function() {
        calculate(this, submit)
      });
    });

  };

})(jQuery);

$(document).ready(function() {
  $("#modal-contact-form-message").charCount($("#modal-contact-form-submit"));
});
<form action="process_contact_form/" method="post" id="modal-contact-form">

  <div>
    <label for="modal-contact-form-name">Name</label>
    <input type="text" name="name_cform" id="modal-contact-form-name">
  </div>

  <div>
    <label for="modal-contact-form-email">E-mail</label>
    <input type="email" name="email_cform" id="modal-contact-form-email">
  </div>

  <div id="subject-line">
    <label for="modal-contact-form-subject">Subject</label>
    <input type="text" name="subject_cform" id="modal-contact-form-subject">
  </div>

  <div id="counter-container">
    <label for="modal-contact-form-message">Message</label>
    <textarea name="message_cform" id="modal-contact-form-message"></textarea>
  </div>

  <input type="hidden" name="formtarget_cform" value="modal" id="modal-contact-form-hidden">

  <button type="submit" name="submit_cform" id="modal-contact-form-submit">Send Message</button>

  <p id="modal-contact-form-responses"></p>

</form>

你可以用像这样的标志来做到这一点: 或者您可以 运行 提交开始时加载叠加层

$('form').submit(function () {
    $("#overlay").fadeIn(30);// Call (Show) loading box by default.
    if (Page_ClientValidate() != null) //Check if there is a validation on page.
        {
        if (!Page_ClientValidate()) {//If Validation returns false then hide the loading box
            $("#overlay").hide();
        } 
    }
});

首先,您可以在提交表单时禁用提交按钮。这可以防止任何不必要的进一步表单提交。 然后通过 jqXHR.always() 方法完成 ajax 请求后删除 disabled 属性。

您还可以将按钮的文本更改为 Sending Message...,以便用户知道表单正在提交。

请将此部分<!-- AJAX form messaging -->更改为

$(function() {

    // get the form
    var form = $('#modal-contact-form');

    // get the messages element
    var formMessages = $('#modal-contact-form-responses');

    // get the submit button
    var submitButton = $("#modal-contact-form-submit");

    // set up event listener for contact form
    $(form).submit(function(e) {
        // disable html submit button
        e.preventDefault();

        // serialize form data
        var formData = $(form).serialize();

        // disable submit button to prevent unnecessary submission
        submitButton.attr('disabled', 'disabled');
        submitButton.text('Sending Message...'); // this help the user to know that the form is sending

        // submit form using AJAX
        $.ajax({
            type: 'POST',
            url: $(form).attr('action'),
            data: formData
        })
        .done(function(response) {
            // make sure formMessages element has 'success' class
            $(formMessages).removeClass('error');
            $(formMessages).addClass('success');

            // set message text
            $(formMessages).text('Your message has been sent. Thank you!');

            // clear form
            $('input, textarea').val('');
            $("#modal-contact-form-message").trigger('change');
        })
        .fail(function(data) {
            // make sure formMessages element has 'error' class
            $(formMessages).removeClass('success');
            $(formMessages).addClass('error');

            // set the message text
            $(formMessages).text('Input error. Please review and re-submit.');
        }).always(function(data) { // this will always fire even if the request fails
            submitButton.removeAttr('disabled');
            submitButton.text('Send Message');
        });

    });
});