programing

jQuery에서 양식 이중 제출 방지

bestprogram 2023. 8. 25. 23:48

jQuery에서 양식 이중 제출 방지

나는 서버가 처리하는 데 시간이 조금 걸리는 양식을 가지고 있습니다.사용자가 기다리면서 단추를 다시 클릭하여 양식을 다시 제출하지 않도록 해야 합니다.다음 jQuery 코드를 사용해 보았습니다.

<script type="text/javascript">
$(document).ready(function() {
    $("form#my_form").submit(function() {
        $('input').attr('disabled', 'disabled');
        $('a').attr('disabled', 'disabled');
        return true;
    });
});
</script>

Firefox에서 이것을 시도하면 모든 것이 비활성화되지만 폼이 포함되어야 할 POST 데이터와 함께 제출되지 않습니다.여러 개의 제출 버튼이 있고 POST에 어떤 사람의 값이 포함되어 있는지 결정하기 때문에 양식과 함께 제출할 버튼이 필요하기 때문에 jQuery를 사용하여 양식을 제출할 수 없습니다.저는 평소와 같이 양식을 제출해야 하고, 그 이후에는 즉시 모든 것을 비활성화해야 합니다.

감사합니다!

2018년 업데이트: 저는 이 오래된 답변에 대해 몇 가지 포인트를 얻었고, 가장 좋은 해결책은 중복 제출이 무해하도록 작업을 동일하게 만드는 것이라고 덧붙이고 싶습니다.

예를 들어, 양식이 주문을 작성하는 경우 양식에 고유 ID를 입력합니다.서버는 해당 ID의 주문 작성 요청을 처음 볼 때 해당 ID를 작성하고 "성공"으로 응답해야 합니다.이후 제출 시에도 "성공"으로 응답해야 하지만(클라이언트가 첫 번째 응답을 받지 못한 경우) 아무것도 변경해서는 안 됩니다.

중복되는 항목은 데이터베이스의 고유성 검사를 통해 탐지하여 레이스 상태를 방지해야 합니다.


당신의 문제는 다음과 같습니다.

$('input').attr('disabled','disabled');

양식이 제출해야 할 데이터를 포함하여 모든 입력을 비활성화하고 있습니다.

제출 단추만 비활성화하려면 다음 작업을 수행합니다.

$('button[type=submit], input[type=submit]').prop('disabled',true);

하지만 저는 그 버튼들조차 비활성화되어 있다면 IE가 양식을 제출하지 않을 것이라고 생각합니다.저는 다른 접근법을 제안하고 싶습니다.

이를 해결하기 위한 jQuery 플러그인

우리는 방금 아래 코드로 이 문제를 해결했습니다.여기요jQuery를 사용하는 입니다.data()양식을 이미 제출했는지 여부를 표시합니다.그렇게 하면 제출 버튼을 조작할 필요가 없어 IE를 놀라게 할 수 있습니다.

// jQuery plugin to prevent double submission of forms
jQuery.fn.preventDoubleSubmission = function() {
  $(this).on('submit',function(e){
    var $form = $(this);

    if ($form.data('submitted') === true) {
      // Previously submitted - don't submit again
      e.preventDefault();
    } else {
      // Mark it so that the next submit can be ignored
      $form.data('submitted', true);
    }
  });

  // Keep chainability
  return this;
};

다음과 같이 사용합니다.

$('form').preventDoubleSubmission();

페이지 로드당 여러 번 제출할 수 있는 AJAX 양식이 있는 경우 다음과 같이 클래스를 지정한 다음 셀렉터에서 제외할 수 있습니다.

$('form:not(.js-allow-double-submission)').preventDoubleSubmission();

타이밍 접근 방식이 잘못되었습니다. 클라이언트 브라우저에서 작업이 얼마나 오래 걸릴지 어떻게 알 수 있습니까?

방법

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

양식을 제출하면 양식 내부의 모든 제출 단추가 비활성화됩니다.

Firefox에서 단추를 비활성화하면 이 상태가 기록으로 돌아갈 때 기억됩니다.예를 들어, 페이지 로드 시 단추를 사용 가능으로 설정해야 합니다.

네이선 롱의 대답이 가야 할 길이라고 생각합니다.저는 클라이언트 측 검증을 사용하고 있기 때문에 양식이 유효하다는 조건만 추가했습니다.

편집: 추가하지 않으면 클라이언트 측 유효성 검사에서 오류가 발생할 경우 사용자는 양식을 제출할 수 없습니다.

        // jQuery plugin to prevent double submission of forms
        jQuery.fn.preventDoubleSubmission = function () {
            $(this).on('submit', function (e) {
                var $form = $(this);

                if ($form.data('submitted') === true) {
                    // Previously submitted - don't submit again
                    alert('Form already submitted. Please wait.');
                    e.preventDefault();
                } else {
                    // Mark it so that the next submit can be ignored
                    // ADDED requirement that form be valid
                    if($form.valid()) {
                        $form.data('submitted', true);
                    }
                }
            });

            // Keep chainability
            return this;
        };

event.timeStampFirefox에서는 작동하지 않습니다.을 반환하는 이므로, 은 전화를 . 전화하십시오.event.preventDefault()그리고 우리가 그것을 하는 동안, 항상 제어 구조가 있는 교정기를 사용하세요.

이전의 모든 답변을 요약하면, 이 작업을 수행하고 크로스 브라우저로 작동하는 플러그인이 있습니다.

jQuery.fn.preventDoubleSubmission = function() {

    var last_clicked, time_since_clicked;

    jQuery(this).bind('submit', function(event) {

        if(last_clicked) {
            time_since_clicked = jQuery.now() - last_clicked;
        }

        last_clicked = jQuery.now();

        if(time_since_clicked < 2000) {
            // Blocking form submit because it was too soon after the last submit.
            event.preventDefault();
        }

        return true;
    });
};

Kern3l을 해결하기 위해, 타이밍 방법은 단순히 제출 버튼의 더블 클릭을 멈추려고 하기 때문에 저에게 효과가 있습니다.제출에 대한 응답 시간이 매우 길면 제출 단추나 양식을 스피너로 교체하는 것이 좋습니다.

위의 예 대부분이 그렇듯이 양식의 후속 제출을 완전히 차단하면 한 가지 나쁜 부작용이 있습니다. 네트워크 오류가 발생하여 다시 제출하려고 하면 이를 수행할 수 없고 변경한 내용이 손실됩니다.이것은 분명 사용자를 화나게 할 것입니다.

jquery-safeform 플러그인을 확인하십시오.

사용 예:

$('.safeform').safeform({
    timeout: 5000,  // disable next submission for 5 sec
    submit: function() {
        // You can put validation and ajax stuff here...

        // When done no need to wait for timeout, re-enable the form ASAP
        $(this).safeform('complete');
        return false;
    }
});

...그러나 양식이 포함되어야 할 POST 데이터와 함께 제출되지 않았습니다.

맞아요.비활성화된 양식 요소 이름/값은 서버로 전송되지 않습니다.읽기 전용 요소로 설정해야 합니다.

또한 앵커는 그렇게 비활성화될 수 없습니다.다음과 같이 HREF를 제거하거나(권장하지 않음) 기본 동작을 방지해야 합니다(더 나은 방법).

<script type="text/javascript">
$(document).ready(function(){
    $("form#my_form").submit(function(){
      $('input').attr('readonly', true);
      $('input[type=submit]').attr("disabled", "disabled");
      $('a').unbind("click").click(function(e) {
          e.preventDefault();
          // or return false;
      });
    });
</script>

Nathan Long의 접근 방식을 개선할 가능성이 있습니다.이미 제출된 양식의 탐지 논리를 다음과 같은 논리로 대체할 수 있습니다.

var lastTime = $(this).data("lastSubmitTime");
if (lastTime && typeof lastTime === "object") {
    var now = new Date();
    if ((now - lastTime) > 2000) // 2000ms
        return true;
    else
        return false;
}
$(this).data("lastSubmitTime", new Date());
return true; // or do an ajax call or smth else

Nathan 코드만 jQuery Validate 플러그인용

jQuery Validate 플러그인을 사용하는 경우 이미 제출 처리기가 구현되어 있으므로 둘 이상을 구현할 이유가 없습니다.코드:

jQuery.validator.setDefaults({
  submitHandler: function(form){
    // Prevent double submit
    if($(form).data('submitted')===true){
      // Previously submitted - don't submit again
      return false;
    } else {
      // Mark form as 'submitted' so that the next submit can be ignored
      $(form).data('submitted', true);
      return true;
    }
  }
});

내부에서 쉽게 확장할 수 있습니다.} else {-block - 입력 및/또는 제출 버튼을 비활성화합니다.

건배.

이것으로 두 번째 제출을 중지할 수 있습니다.

$("form").submit(function() {
        // submit more than once return false
        $(this).submit(function() {
            return false;
        });
        // submit once return true
        return true; // or do what you want to do
    });
});

저는 이 게시물의 아이디어를 사용하여 At Zako 버전과 매우 유사한 해결책을 생각하게 되었습니다.

 jQuery.fn.preventDoubleSubmission = function() {

    var last_clicked, time_since_clicked;

    $(this).bind('submit', function(event){

    if(last_clicked) 
      time_since_clicked = event.timeStamp - last_clicked;

    last_clicked = event.timeStamp;

    if(time_since_clicked < 2000)
      return false;

    return true;
  });   
};

다음과 같이 사용:

$('#my-form').preventDoubleSubmission();

일종의 제한 시간을 포함하지 않고 제출을 비활성화하거나 양식 요소를 비활성화한 솔루션이 문제를 일으킨다는 것을 발견했습니다. 잠금이 트리거되면 페이지를 새로 고칠 때까지 다시 제출할 수 없기 때문입니다.그것은 나에게 아약스 일을 할 때 약간의 문제를 일으킵니다.

이것은 그렇게 화려하지 않기 때문에 아마 조금 더 예쁘게 만들 수 있을 것입니다.

AJAX를 사용하여 양식을 게시하는 경우, 설정async: false는 양식이 삭제되기 전에 추가 제출을 방지해야 합니다.

$("#form").submit(function(){
    var one = $("#one").val();
    var two = $("#two").val();
    $.ajax({
      type: "POST",
      async: false,  // <------ Will complete submit before allowing further action
      url: "process.php",
      data: "one="+one+"&two="+two+"&add=true",
      success: function(result){
        console.log(result);
        // do something with result
      },
      error: function(){alert('Error!')}
    });
    return false;
   }
});

부트스트랩 3을 위해 Nathan의 솔루션을 약간 수정했습니다.텍스트 로드를 제출 단추로 설정합니다.또한 30초 후에는 시간이 초과되고 양식을 다시 제출할 수 있습니다.

jQuery.fn.preventDoubleSubmission = function() {
  $('input[type="submit"]').data('loading-text', 'Loading...');

  $(this).on('submit',function(e){
    var $form = $(this);

    $('input[type="submit"]', $form).button('loading');

    if ($form.data('submitted') === true) {
      // Previously submitted - don't submit again
      e.preventDefault();
    } else {
      // Mark it so that the next submit can be ignored
      $form.data('submitted', true);
      $form.setFormTimeout();
    }
  });

  // Keep chainability
  return this;
};

jQuery.fn.setFormTimeout = function() {
  var $form = $(this);
  setTimeout(function() {
    $('input[type="submit"]', $form).button('reset');
    alert('Form failed to submit within 30 seconds');
  }, 30000);
};

두 개의 제출 버튼을 사용합니다.

<input id="sub" name="sub" type="submit" value="OK, Save">
<input id="sub2" name="sub2" type="submit" value="Hidden Submit" style="display:none">

그리고 jQuery:

$("#sub").click(function(){
  $(this).val("Please wait..");
  $(this).attr("disabled","disabled");
  $("#sub2").click();
});

제출 시 간단한 카운터를 사용합니다.

    var submitCounter = 0;
    function monitor() {
        submitCounter++;
        if (submitCounter < 2) {
            console.log('Submitted. Attempt: ' + submitCounter);
            return true;
        }
        console.log('Not Submitted. Attempt: ' + submitCounter);
        return false;
    }

그리고 전화monitor()양식을 제출할 때 기능합니다.

    <form action="/someAction.go" onsubmit="return monitor();" method="POST">
        ....
        <input type="submit" value="Save Data">
    </form>

저도 비슷한 문제를 겪고 있는데 제 해결책은 다음과 같습니다.

클라이언트 측 유효성 검사가 없는 경우 여기에 설명된 대로 jquery one() 메서드를 사용하면 됩니다.

http://api.jquery.com/one/

이렇게 하면 핸들러가 호출된 후에 핸들러가 비활성화됩니다.

$("#mysavebuttonid").on("click", function () {
  $('form').submit();
});

만약 당신이 나처럼 클라이언트 측 검증을 한다면, 그것은 조금 더 까다롭습니다.위의 예에서는 유효성 검사에 실패한 후 다시 제출할 수 없습니다.대신 이 방법을 사용해 보십시오.

$("#mysavebuttonid").on("click", function (event) {
  $('form').submit();
  if (boolFormPassedClientSideValidation) {
        //form has passed client side validation and is going to be saved
        //now disable this button from future presses
        $(this).off(event);
   }
});

jQuery 유효성 검사 플러그인을 가져오지 않는 한 이러한 모든 솔루션을 사용할 수 있습니다.

예를 들어 클라이언트가 잘못된 입력을 입력하고 양식을 제출하면 jQuery 유효성 검사에서 잘못된 입력을 탐지하는지 여부에 관계없이 단추가 비활성화됩니다.그러면 고객은 입력을 수정한 후에 양식을 다시 제출할 수 없습니다.

이 문제에 대한 해결 방법은 다음과 같은 경우에만 사용되었습니다.

$('form').submit(function () {
    if ($(this).valid()) {
        $(this).find("input[type='submit']").prop('disabled', true);
    }
});

이 코드를 글로벌로 가져온 JavaScript 파일에 추가한 후 웹 사이트에 양식을 두 번 게시하지 못했습니다.

내 솔루션:

// jQuery plugin to prevent double submission of forms
$.fn.preventDoubleSubmission = function () {
    var $form = $(this);

    $form.find('[type="submit"]').click(function () {
        $(this).prop('disabled', true);
        $form.submit();
    });

    // Keep chainability
    return this;
};

저의 경우, 제출 시 양식에 유효성 검사 코드가 있으므로 제출 시 체크포인트를 포함하여 Nathan Long 답변을 증분합니다.

$.fn.preventDoubleSubmission = function() {
      $(this).on('submit',function(e){
        var $form = $(this);
        //if the form has something in onsubmit
        var submitCode = $form.attr('onsubmit');
        if(submitCode != undefined && submitCode != ''){
            var submitFunction = new Function (submitCode);
            if(!submitFunction()){
                event.preventDefault();
                return false;
            }                   
        }

        if ($form.data('submitted') === true) {
            /*Previously submitted - don't submit again */
            e.preventDefault();
        } else {
          /*Mark it so that the next submit can be ignored*/
          $form.data('submitted', true);
        }
      });

      /*Keep chainability*/
      return this;
    };

제출 변경 버튼:

<input id="submitButtonId" type="submit" value="Delete" />

일반 버튼의 경우:

<input id="submitButtonId" type="button" value="Delete" />

그런 다음 클릭 기능을 사용합니다.

$("#submitButtonId").click(function () {
        $('#submitButtonId').prop('disabled', true);
        $('#myForm').submit();
    });

필요한 경우 다시 활성화 버튼을 기억하십시오.

$('#submitButtonId').prop('disabled', false);

나는 포인터 이벤트의 좋은 구식 CSS 트릭을 믿을 수 없습니다: 아직 언급되지 않았습니다.비활성화된 속성을 추가하여 동일한 문제가 발생했지만 이 문제는 다시 게시되지 않습니다.아래를 시도하고 #SubmitButton을 제출 단추의 ID로 바꿉니다.

$(document).on('click', '#SubmitButton', function () {
    $(this).css('pointer-events', 'none');
})

이것뿐만 아니라 -- 이것은 양식을 제출할 뿐만 아니라 제출 단추도 비활성화할 것입니다.

   $('#myForm').on('submit', function(e) {
       var clickedSubmit = $(this).find('input[type=submit]:focus');
       $(clickedSubmit).prop('disabled', true);
   });

를 사용하는 이 두을 "jQueryValidate" 에 둘 수 .if ($('#myForm').valid()).

이 코드는 버튼 라벨에 로드를 표시하고 버튼을 다음으로 설정합니다.

비활성화 상태, 처리 후 다시 활성화하고 원래 버튼 텍스트를 반환합니다**

$(function () {

    $(".btn-Loading").each(function (idx, elm) {
        $(elm).click(function () {
            //do processing
            if ($(".input-validation-error").length > 0)
                return;
            $(this).attr("label", $(this).text()).text("loading ....");
            $(this).delay(1000).animate({ disabled: true }, 1000, function () {
                //original event call
                $.when($(elm).delay(1000).one("click")).done(function () {
                    $(this).animate({ disabled: false }, 1000, function () {
                        $(this).text($(this).attr("label"));
                    })
                });
                //processing finalized
            });
        });
    });
    // and fire it after definition
});

내가 찾은 가장 좋은 방법은 버튼을 클릭하면 즉시 비활성화하는 것입니다.

$('#myButton').click(function() {
    $('#myButton').prop('disabled', true);
});

필요할 때 다시 활성화합니다. 예:

  • 유효성 검사 실패
  • 서버에서 양식 데이터를 처리하는 동안 오류가 발생한 다음 jQuery를 사용한 오류 응답 후

다음을 사용하여 매우 유사한 문제를 해결했습니다.

$("#my_form").submit(function(){
    $('input[type=submit]').click(function(event){
        event.preventDefault();
    });
});

언급URL : https://stackoverflow.com/questions/2830542/prevent-double-submission-of-forms-in-jquery