1

サイトの投票メカニズムを構築しています。Stackoverflow で見られる同様のもの。

たとえば、ユーザーが上矢印をクリックすると、vote = True. 彼がもう一度クリックすると、vote = None. 投票を非常に迅速に送信する場合を除いて、アプリは正常に動作しています。

矢印を非常に速くクリックし、データをログに記録して投票がどのように行われているかを確認しようとしました。残念ながら、いくつかの不正行為が見られます。高速とは、つまり、数秒間停止することなく、矢印を連続してクリックすることです!

予想されるログ データは次のようになります。

vote=True
vote=None
vote=True
vote=None
..

しかし、私はそれを次のように観察しました

vote=True
vote=True
vote=None
vote=None

2 番目のケースとして言及された観察されたログ データは、少し順不同のようです。これは、django によって受信された要求がキューとして処理されていないことを意味している可能性があります。私たちの場合、これは少し危険です。または、データベースの保存に時間がかかっており、その間に別のリクエストが処理され、エラーが発生しています。

あなたが私の問題を理解していることを願っています。それで、ここで何が起こっているのか、それを制御する方法を教えていただけないでしょうか。

4

2 に答える 2

1

ブラウザーが (非同期) リクエストを送信する順序、サーバーに到着する順序、および単一または複数インスタンス (スレッド化されたワーカー) Django アプリケーションによって処理される順序について、仮定を立てることはできません。

したがって、上で説明したことは、実際に期待できることです。同期リクエストを行うと、少し役立つ場合があります。最良のオプションは、おそらく (非同期的に) サーバーの応答を待ってから、それ以上のクリックを許可することです。

于 2013-09-17T13:11:40.600 に答える
0

次のようなフローが必要です。

-> User clicks button
-> check if user has already voted up
-> if no:
    -> vote up request goes
    -> vote up after validation
    -> response is sent back to browser
-> else:
    -> vote none request goes
    -> remove the vote after validation
    -> response is sent back to browser

リクエストがすでに送信され、その応答が待機されているときにボタンを無効にしないと、このような状況に陥ります。

たとえば、request1 は賛成票と見なされ、リクエストが送信されました。

request1 の応答が返されてユーザーが再度クリックする前に、この要求も賛成票と見なされますが、これは期待どおりではありません。

  • ajax 呼び出しを行う直前にボタンを無効にし、応答を受信したら再度有効にする必要があります。
  • または、ユーザーがクリックするたびに、ajax 呼び出しを行う前であっても、ボタンの種類を反転する必要があります。そして ajax レスポンスを受信したら、前のアクションを再度検証します。ユーザーが投票する権限を持っていないなど、サーバー側で検証が失敗した場合にのみ異なります。

自分の投稿に投票しようとすると、SOでこれが起こっているのを見ることができます。最初に投票なしモードに変更し、後でサーバーから応答を受信すると元に戻り、エラーメッセージも表示します。

PS: 教育目的でのみ、自分の投稿に投票しようとしました ;)

于 2013-09-17T13:15:48.257 に答える