web-dev-qa-db-ja.com

フォームがクライアント側から複数回送信されるのを防ぐ方法は?

応答が遅い場合、送信ボタンを複数回クリックすることがあります。

これを防ぐにはどうすればいいですか?

85
omg

控えめなJavaScriptを使用して、フォームが既に送信された後、フォームの送信イベントを無効にします。 jQueryを使用した例を次に示します。

編集:送信ボタンをクリックせずにフォームを送信する問題を修正しました。ありがとう、いちばん。

$("body").on("submit", "form", function() {
    $(this).submit(function() {
        return false;
    });
    return true;
});
93
vanstee

私は vansteeのソリューション とasp mvc 3の控えめな検証を試みましたが、クライアントの検証が失敗した場合、コードはまだ実行され、フォーム送信は完全に無効になります。フィールドを修正した後に再送信することはできません。 (bjanのコメントを参照)

そこで、vansteeのスクリプトを次のように変更しました。

$("form").submit(function () {
    if ($(this).valid()) {
        $(this).submit(function () {
            return false;
        });
        return true;
    }
    else {
        return false;
    }
});
38
m irina

クライアント側のフォーム送信制御は、onsubmitハンドラーが送信ボタンを非表示にし、それをロードアニメーションに置き換えることにより、非常にエレガントに実現できます。そうすることで、ユーザーは自分のアクション(クリック)が発生した同じ場所で即座に視覚的なフィードバックを得ることができます。同時に、フォームが再度送信されるのを防ぎます。

XHRを介してフォームを送信する場合、タイムアウトなどの送信エラーも処理する必要があることに注意してください。ユーザーフォームを再送信する必要があるため、送信ボタンを再度表示する必要があります。

別の注意として、llimllibは非常に有効なポイントを提示します。 Allフォームの検証はサーバー側で行う必要があります。これには、複数の提出チェックが含まれます。 クライアントを信頼しないでください!これは、javascriptが無効になっている場合だけではありません。すべてのクライアント側コードを変更できることに注意してください。想像するのはやや難しいですが、サーバーと通信するhtml/javascriptは、必ずしも作成したhtml/javascriptとは限りません。

Llimllibが示唆するように、そのフォームに固有の識別子を持つフォームを生成し、非表示の入力フィールドに配置します。その識別子を保存します。フォームデータを受信する場合は、識別子が一致した場合にのみ処理します。 (識別子をユーザーセッションにリンクし、さらにセキュリティを強化するために一致させます。)データ処理後、識別子を削除します。

もちろん、時々、フォームデータが送信されたことのない識別子をクリーンアップする必要があります。しかし、おそらくあなたのウェブサイトは既に何らかの種類の「ガベージコレクション」メカニズムを採用しています。

22
Rob
<form onsubmit="if(submitted) return false; submitted = true; return true">
14
chaos

これを行う簡単な方法を次に示します。

<form onsubmit="return checkBeforeSubmit()">
  some input:<input type="text">
  <input type="submit" value="submit" />
</form>

<script type="text/javascript">
  var wasSubmitted = false;    
    function checkBeforeSubmit(){
      if(!wasSubmitted) {
        wasSubmitted = true;
        return wasSubmitted;
      }
      return false;
    }    
</script>
14
ichiban

クリック後すぐに送信ボタンを無効にします。検証を適切に処理してください。また、すべての処理またはDB操作の中間ページを保持してから、次のページにリダイレクトします。これにより、2番目のページを更新しても別の処理が行われないようになります。

8
Shoban

現在の時刻をハッシュし、フォーム上の非表示の入力にします。サーバー側で、各フォーム送信のハッシュを確認します。すでにそのハッシュを受け取っている場合は、繰り返し送信します。

編集:javascriptに依存することは良いアイデアではないので、あなたはすべてそれらのアイデアを支持し続けることができますが、一部のユーザーはそれを有効にしません。正しい答えは、サーバー側でのユーザー入力を信頼しないことです。

5
llimllib

フォームが処理中であることを示すために、進行状況バーまたはスピナーを表示することもできます。

5
Tony Borf

JQueryを使用すると、次のことができます。

$('input:submit').click( function() { this.disabled = true } );

   $('input:submit').keypress( function(e) {
     if (e.which == 13) {
        this.disabled = true 
     } 
    }
   );
5
Boris Guéry

「javascript」で質問にタグを付けたことは知っていますが、javascriptにまったく依存しないソリューションは次のとおりです。

これは[〜#〜] prg [〜#〜]という名前のwebappパターンであり、これを説明する good article

4
Pablo Fernandez

単に複数の送信を防ぐことができます:

var Workin = false;

$('form').submit(function()
{
   if(Workin) return false;
   Workin =true;

   // codes here.
   // Once you finish turn the Workin variable into false 
   // to enable the submit event again
   Workin = false;

});
4
Alpha

この質問に対する最も単純な答えは、「応答が遅い場合、送信ボタンを複数回クリックすることがあります。これを防ぐにはどうすればよいですか?」

以下のコードのように、フォーム送信ボタンを無効にします。

<form ... onsubmit="buttonName.disabled=true; return true;">
  <input type="submit" name="buttonName" value="Submit">
</form>

送信のための最初のクリックで、送信ボタンを無効にします。また、いくつかの検証ルールがある場合は、正常に機能します。それが役立つことを願っています。

3
Imran Khan

safeform jqueryプラグインを試すことができます。

$('#example').safeform({
    timeout: 5000, // disable form on 5 sec. after submit
    submit: function(event) {
        // put here validation and ajax stuff...

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

クライアント側では、@ vansteeおよび@chaosによって提供されるメソッドのようなjavascriptコードでフォームが送信されたら、送信ボタンを無効にする必要があります。

しかし、ネットワークラグやjavascriptが無効になっている状況では、JSに依存してこれを防ぐべきではないという問題があります。

したがって、サーバー側、同じクライアントからの繰り返し送信を確認し、ユーザーからの誤った試みと思われる繰り返しの送信を省略する必要があります。

3
steveyang

私にとって最もシンプルでエレガントなソリューション:

function checkForm(form) // Submit button clicked
{
    form.myButton.disabled = true;
    form.myButton.value = "Please wait...";
    return true;
}

<form method="POST" action="..." onsubmit="return checkForm(this);">
    ...
    <input type="submit" name="myButton" value="Submit">
</form>

その他のリンク...

1
Solis

Form.itでこのコードを使用して、複数のクリックを処理します。

<script type="text/javascript">
    $(document).ready(function() {
        $("form").submit(function() {
            $(this).submit(function() {
                return false;
            });
            return true;
        });     
    }); 
</script>

確実に機能します。

1
Bachas

ブラウザの入力検証をバイパスせずに、可能な答えに追加するだけ

$( document ).ready(function() {
    $('.btn-submit').on('click', function() {
        if(this.form.checkValidity()) {
            $(this).attr("disabled", "disabled");
            $(this).val("Submitting...");
            this.form.submit();
        }
    });
});
0
Roi

最も単純な解決策は、クリック時にボタンを無効にし、操作の完了後に有効にすることです。 jsfiddleで同様のソリューションを確認するには:

[click here][1]

そして、あなたはこれに関する他の解決策を見つけることができます answer

0
Kalyani

これにより、2秒ごとに送信できます。フロント検証の場合。

$(document).ready(function() {
    $('form[debounce]').submit(function(e) {
        const submiting = !!$(this).data('submiting');

        if(!submiting) {
            $(this).data('submiting', true);

            setTimeout(() => {
                $(this).data('submiting', false);
            }, 2000);

            return true;
        }

        e.preventDefault();
        return false;
    });
})
0
Aurel

Javascriptを使用してこれを行うには少し簡単です。以下は、必要な機能を提供するコードです。

$('#disable').on('click', function(){
    $('#disable').attr("disabled", true);
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="disable">Disable Me!</button>
0
Rish

以前に提案されたものに代わるものは次のとおりです。

jQuery('form').submit(function(){
     $(this).find(':submit').attr( 'disabled','disabled' );
     //the rest of your code
});

複数の送信を防ぐ最良の方法は、メソッドにボタンIDを渡すことです。

    function DisableButton() {
        document.getElementById("btnPostJob").disabled = true;
    }
    window.onbeforeunload = DisableButton; 
0
user2427182

これは非常にうまく機能します。ファームを送信してボタンを無効にし、2秒後にボタンをアクティブにします。

<button id="submit" type="submit" onclick="submitLimit()">Yes</button>

function submitLimit() {
var btn = document.getElementById('submit')
setTimeout(function() {
    btn.setAttribute('disabled', 'disabled');
}, 1);

setTimeout(function() {
    btn.removeAttribute('disabled');
}, 2000);}

ECMA6 Syntexで

function submitLimit() {
submitBtn = document.getElementById('submit');

setTimeout(() => { submitBtn.setAttribute('disabled', 'disabled') }, 1);

setTimeout(() => { submitBtn.removeAttribute('disabled') }, 4000);}
0
Awais Jameel