12

背景:登録/支払いページを作成中です。私たちの哲学は、最初にサーバー側ですべての検証とエラーチェックをコーディングし、次に2番目のステップとしてクライアント側の検証を追加することでした(邪魔にならないjQuery)。

サーバー側のダブルクリックを無効にしたかったので、同時投稿/競合状態を処理するためのロックされたスレッドセーフなコードを作成しました。これをテストしようとすると、ポストまたは競合状態を同時に発生させることはできないことに気付きました。

(とにかく古いブラウザでは)送信ボタンをダブルクリックすると、次のように機能すると思いました。

  • ユーザーが送信ボタンをダブルクリックします。
  • ブラウザは最初のクリックで投稿を送信します
  • 2回目のクリックで、ブラウザは最初の投稿をキャンセル/無視し、2番目の投稿を開始します(最初の投稿が応答とともに返される前)。
  • ブラウザは、最初の投稿応答を無視して、2番目の投稿が戻るのを待ちます。

サーバー側から見ると、サーバーは2つの同時投稿要求を受け取り、実行して両方に応答します(最初の応答を誰も聞いていないことに気づいていません)。

私たちのテスト(FireFox 3.0、IE 8.0)から、これは実際に起こることです:

  • ユーザーが送信ボタンをダブルクリック
  • ブラウザは最初のクリックで投稿を送信します
  • ブラウザは2回目のクリックをキューに入れますが、最初のクリックからの応答を待ちます。
  • 最初のクリックから応答が返されます(応答は無視されますか?)。
  • ブラウザは2回目のクリックで投稿を送信します。

したがって、サーバー側から:サーバーは単一の投稿を受信し、それを実行して応答します。次に、サーバーは2番目の要求を受信し、それを実行して応答します。

私の質問は、これは常にこのように機能しましたか(そして私は私の心を失っています)?それとも、これは最新のブラウザの新機能であり、同時投稿がサーバーに送信されるのを防ぎますか?

サーバー側のダブルクリック防止については、同時投稿や競合状態を気にする必要がないようです。キューに入れられた投稿についてのみ心配する必要があります。

4

3 に答える 3

4

処理する必要がある同様の状況 (javascript disable-submit-button ソリューションではカバーされない) は、ユーザーが [送信] をクリックし、サーバーが要求を処理するが、処理中にユーザーのインターネット接続がダウンする場合です (おそらく彼らはトンネルに入る電車に乗っています)。

電車がトンネルを出たとき、ユーザーはトランザクションが成功したかどうかわかりません。ユーザーはボタンを押しましたが、ページに何も変化がありませんでした (または、「再試行」ページが表示された可能性があります)。彼らがするのは自然なことで、もう一度 [送信] (または [再試行] ボタン) をクリックします。

この状況を処理する最善の方法は、一意のトランザクション ID をフォーム (隠しフィールド) に含めることです。この ID をランダムに生成し、トランザクションが正常に処理されたら、完了したトランザクションのリストとしてデータベースに保存します。

次に、POST を取得したら、このトランザクションが既に表示されているかどうかを確認します。表示されている場合は、ステータス ページに直接スキップします。だいたい:

BEGIN TRANSACTION

SELECT *
FROM completedTransactions
WHERE userId = ... AND transactionId = ...

<if we got a result - display results of previous transaction>

<otherwise - process the request as normal>

INSERT INTO completedTransactions (userId, transactionId)
VALUES (....)

END TRANSACTION

これには、(トランザクションを適切にサポートするデータベースがあれば - 支払いを処理しているので、そうすることを願っています!)スレッド化やロックを行う必要がなく、物事が「うまくいく」という利点があります。

(注意してください - 一部のデータベース システムは、同時実行性の問題がある場合、トランザクションを任意に中止できます - しかし、この (まれな) 状況は、再試行ループを使用して簡単に対処できます...)

ブラウザからのダブルクリックのテストに関して: 2 回の「送信」クリックの間に「停止」ボタンを押しても違いはありますか?

于 2010-05-19T18:26:03.860 に答える
1

これはばかげた応答かもしれませんが、クリック時に JavaScript を使用して送信ボタンを無効にしないでください。複数のクリックについて心配する必要はありません。私は通常、私が作成するほとんどのフォームでこれを行い、問題を解決しているようです。

あなたはすでにJavaScriptを使用していると言っているので、それは問題ではありませんか?

于 2010-05-19T01:42:13.190 に答える
0

リクエストが接続または送信段階にある限り、最初の送信中に送信をクリックすると、サーバーが「認識」することなく新しいリクエストが開始され、リクエストがキャンセルされます。

于 2010-05-08T05:59:42.633 に答える