14

まあ、すべてはタイトルにありますが、もう少し説明します:-)

私の Rails アプリには多くのフォームが含まれています (Ajax 化されているかどうかに関係なく)。

ユーザーがフォームを 2 回以上送信するのを防ぐために、Javascript を使用しています。

Ajax化されたフォームの私のシナリオがあります:

  • ユーザーがフォームを送信 (クリックまたは入力)
  • JavaScriptは送信ボタンを無効にします
  • Rails コントローラーが処理を行います (Soap リクエストや DB への挿入など)
  • Railsコントローラーはページを更新し、必要に応じて送信ボタンを有効にします(エラーの場合)

ここで、ユーザーが JavaScript をバイパスした場合に、サーバー側のコードを追加して、物事を本当にきれいに保ちたいと考えています。

助言がありますか?

4

8 に答える 8

9

オプション:disable_with => "PleaseWait..."を送信タグに追加できます。

于 2012-07-17T13:15:15.497 に答える
9

私は 4 つのシナリオで 4 つの方法を使用しています。

ユーザーのクリックのみの制限:

stopImmediatePropagation を使用して、クリック イベントをターゲット DOM に追加します。

  /**
   * 防止按钮重复点击。
   * NOTICE: #1 需要在作用点之前调用此方法 #2 stopImmediatePropagation 会阻止后面的所有事件包括事件冒泡
   * @delay_duration 两次点击的间隔时间
   */
  $.fn.preventMultipleClick = function (delay_duration) {
    delay_duration = delay_duration || 3000;
    var last_click_time_stamp = 0;
    var time_duration = 0;
    $(this).bind('click', function (event) {
      time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0;
      //console.debug("preventMultipleClick", last_click_time_stamp, time_duration);
      if (time_duration && time_duration < delay_duration) {
        event.stopImmediatePropagation();
      } else {
        //console.debug("skip preventMultipleClick~");
        last_click_time_stamp = event.timeStamp;
      }
    });
  };

ajax などの送信を制限します。

ajax の beforeSend 属性を使用します。

  /**
   * 使用:
   *   在jquery的ajax方法中加入参数:beforeSend
   *   例如:beforeSend: function(){return $.preventMultipleAjax(event, 5000)}
   *
   * @param event
   * @param delay_duration
   * @returns {boolean}
   */
  $.preventMultipleAjax = function (event, delay_duration) {
    delay_duration = delay_duration || 3000;
    var target = $(event.target);
    var last_click_time_stamp = target.attr("_ajax_send_time_stamp") || 0;
    var time_duration = last_click_time_stamp ? event.timeStamp - last_click_time_stamp : 0;
    //console.debug("preventMultipleAjax", last_click_time_stamp, time_duration);
    if (time_duration && time_duration < delay_duration) {
      return false;
    } else {
      //console.debug("skip preventMultipleAjax~");
      target.attr("_ajax_send_time_stamp", event.timeStamp);
      return true;
    }
  };

フォームのみ:

<%= f.submit "Save annotation", :disable_with => "Saving...", :class => "btn btn-primary", :id => "annotation-submit-button" %>

または: 無効にする: 仅仅対表单要素

<input type="submit" value="submit" />
<input type="button" value="button" />
<input type="image" value="image" />

その他:

これが宝石です:<a href="https://github.com/mlanett/redis-lock" rel="nofollow noreferrer">https://github.com/mlanett/redis-lock

Redis.current.lock("#{current_user.id}.action_name") do
   # Some code
end
于 2013-11-23T11:57:29.433 に答える
8

Redis のロックを使用して、ブロックを次のようなもので囲みます。

Redis.current.lock("#{current_user.id}.action_name") do
   # Some code
end

これは私が使用している宝石です https://github.com/mlanett/redis-lock

于 2013-02-19T20:30:41.067 に答える
2

これが私がすることです:

  1. 変更されようとしているdb内のオブジェクトに「トークン」フィールドを追加します。
  2. そのトークンを、そのオブジェクトを変更するフォームに入れます。
  3. 変更後すぐに、そのオブジェクトをNEWトークンで保存します。
  4. そのトークンを他のページビューで使用します。

これは二重提出を防ぐことはできませんが、少なくとも2回目のコミットからの変更を防ぐことができます。つまり、ユーザーが2回目にフォームを送信すると、コードは送信されたトークンをデータベース内のトークンと照合し、一致しない場合はオブジェクトを更新しないでください。

これには、新しく作成されたオブジェクトの欠点もあります(つまり、ユーザーがそのようなコメントやsmthを作成したい場合)。ただし、この場合、同じユーザーからの作成時間間隔を確認し、たとえば5秒未満の場合は、オブジェクトが「作成」されないようにすることができます。

于 2010-07-05T08:29:20.433 に答える
1

本当の提案ではありませんが (反対票があっても驚かないでしょう)、あなたのサイトは JS なしでも使用できますか? 通常の操作では JS を有効にする必要があるという適切なメッセージを彼に表示するのはどうですか。

于 2010-07-01T17:32:52.667 に答える
0

これが役立つかどうかわからない:

サーバー側:

  1. フォームの新規ロード時に、session['variable']=false を設定します //フォームがまだ送信されていないことを意味します。

  2. フォームの送信時に、次を確認してください。

    if session['variable'] == true
    {
       do nothing...
    }
    else
    {
       set session['variable'] = true;
      //do submit logic here
    }
    
于 2010-07-05T09:01:54.617 に答える
0

1) 何かが起こっていること、リクエストが処理されていることをユーザーに知らせるために、何らかの移動インジケーターも表示すると便利です。多くの二重送信を排除する必要があります。

2) ユーザーが JavaScript を無効にしている場合、「ajax化された」フォームをどのように送信しますか? サイトが javascript なしで機能しなくなった場合は、ユーザーに通知するのがおそらく最善です ( Eimantasが提案するように)。

1 で何を意味するかを明確にするために、そのような指標の一例を編集します。
http://www.netzgesta.de/busy/

于 2010-07-01T17:39:36.967 に答える