2010-12-10 1 views
2

私はAjax経由でデータを送信するためにボタンを使用しています。私はボタンを無効にして有効にするためにjQueryを使用しています。これは、ユーザーが悪意のあるか無意識に複数のリクエストを発することができる「ボタンマッシング」を防ぐためです。ボタンの代わりにアンカーを使用する場合、どうやってボタンマッシングを防止できますか?

jQueryでこの動作を防止するための要素にとらわれない方法がありますか?たとえば、ボタンの代わりにアンカーを使用してデータを送信するとします。ボタンを無効にすることができます。アンカーを無効にすることはできません。あなたが行うことができ

<input class="button" type="button" value=""> 
+1

クライアント側ではなくサーバー側で複数のフォームを送信することを検討する必要があります。それはより信頼できます。 – RoToRa

+2

* "これは、ユーザーが複数のリクエストを悪意のあるか無意識に発することができる"ボタンマッシング(button-mashing) "を防ぐためです。*無意識に複数のリクエストを送信しようとするのは良いことですが、悪意のある行為をやめることはできません。サーバーはそれに対して堅牢でなければなりません。 –

+0

ありがとう、私はすでにこれを処理するバックエンドのメカニズムを持っていることに言及しませんでした。私はそのようなイベントでサーバが不必要に攻撃されることを望んでいませんでした。 – Mohamad

答えて

6

もちろん、これを実行する最良の方法は、サーバー側で正常に処理することです。

これは、jQueryでdata storage methodsを使用して、既にクリックされていることを示す値を保存し、それを使用してユーザーが既にボタンをクリックしたかどうかを判断することができます。値はセレクタごとに格納されるため、何にでも設定できます。

$("a").click(function(e) { 
    e.preventDefault(); 

    if (!$(this).data('isClicked')) { 
     var link = $(this); 

     // Your code on successful click 

     // Set the isClicked value and set a timer to reset in 3s 
     link.data('isClicked', true); 
     setTimeout(function() { 
      link.removeData('isClicked') 
     }, 3000); 
    } else { 
     // Anything you want to say 'Bad user!' 
    } 
}); 

利点は、ユーザーが他の要素をクリックするのを止めることではなく、要素ごとの解決策です。あなたの場合は、成功機能でlink.removeDataを実行するとよいでしょう。作業それの

例:http://jsfiddle.net/jonathon/ke8Az/

注意(あなたは3秒以内に再度クリックしてください場合、あなたは「しばらくお待ちください」しかし、あなたはまだ残りの部分をクリックすることができます得ることに注意してください):をこれは、クライアントでありますサイドソリューションのみ。 JavaScriptがインストールされている場合のみ。サーバー側で処理しない限り、ユーザーは悪意を持って複数の要求を送信できます。これはちょうど無意識のうちに役立ちます。

1

:HTML

$('.fav .button').click(function() { 
    $.ajax({ 
    context: this, 
    dataType: 'json', 
    beforeSend: function() { 
    // Toggle state; disable button to prevent button mashing 
    $(".fav").toggleClass("fav-state-1"); 
    $(".fav .button").attr("disabled", true); 
    }, 
    error: function() { 
    // Rollback state and re-enable button on error 
    $(".fav").toggleClass("fav-state-1"); 
    $(".fav .button").attr("disabled", false); 
    }, 
    success: function(response) { 
    if (response.result == "success") { 
    $(".fav .button").attr("disabled", false); 
    } 
    else { 
    // Rollback state; re-enable button 
    $(".fav").toggleClass("fav-state-1"); 
    $(".fav .button").attr("disabled", false); 
    } 
    } 
    }); 
    return false; 
}); 

(私はそれを短くするために不要なコードの一部を削除しました注意してください):ここでは

は、私は今、これをやっている方法です次のようになります。

  1. セットアップ変数をクリックした後に最小秒数。
  2. 要求を起動するメソッドで、それが真であるかどうかを確認し、要求が送信されない場合は
  3. を要求し、変数をtrueに設定していない場合。変数をfalseに戻すsetTimeoutで1秒後に起動するメソッドを設定します。

必要に応じて変数名をカスタマイズする必要があります。変数を正しいスコープに保持する方法を見つける必要がありますが、それは難しくありません。

2

アヤックスコールの前に、クリックされたオブジェクトのクリックイベントをバインド解除し、成功/エラーメソッドでクリックイベントを再バインドできます。

こうすれば、彼らは彼らが望むくらいボタンをマッシュできますが、コールが終了するまではクリックが配線されません。

1

説明している動作を停止する最善の方法は、サーバー側で行うことです。

1

debounceを使用して1回のクリックを登録することもできます。 underscore.jslodash.jsの両方がこの便利な方法を提供します。

ここでは、概念をデモするためのfiddleです。 lazyClickでは、リンクをダブルクリックまたはトリプルクリックできますが、イベントハンドラは1回だけ起動されます。

var lazyClick = _.debounce(onclickHandler, 500); 

function onclickHandler(e){ 
    e.preventDefault(); 
    console.log('clicked'); 
} 

$(function(){ 
    // uncomment this and you will see double clicks are being registered. 
    //$('#btn').click(onclickHandler); 

    // with debounce, only one click will be registered 
    $('#btn').click(lazyClick); 
}); 
関連する問題