[javascript] 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 년 업데이트 : 나는이 오래된 대답에 대한 몇 가지 요점을 얻었으며 최선의 해결책은 중복 제출이 무해하도록 작업을 dem 등원으로 만드는 것입니다.

예를 들어, 양식이 주문을 작성하는 경우 양식에 고유 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에서 버튼을 비활성화하면이 상태는 기록으로 돌아갈 때 기억됩니다. 예를 들어 페이지로드시 버튼을 활성화하지 않도록합니다.


답변

Nathan Long의 대답은 갈 길이라고 생각합니다. 나를 위해 클라이언트 측 유효성 검사를 사용하고 있으므로 양식이 유효한 조건을 추가했습니다.

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

        // 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에서는 작동하지 않습니다. false를 반환하는 것은 표준이 아니므로을 호출해야합니다 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