2009-05-20 7 views
20

Ein häufiges Webproblem ist, dass ein Benutzer mehrfach auf die Schaltfläche Senden eines Formulars klickt, sodass der Server das Formular mehr als einmal verarbeitet. Dies kann auch passieren, wenn ein Benutzer die Zurück-Taste drückt, nachdem er ein Formular gesendet hat, und so wird es erneut verarbeitet.Welche Methoden stehen zur Verfügung, um mehrere Postbacks eines Formulars in ASP.NET MVC zu stoppen?

Was ist der beste Weg, dies in ASP.NET MVC zu verhindern?

Möglichkeiten wie ich es sehe, sind:

  1. die Taste deaktivieren nach einreichen - in dieser Runde die mehrere Klicks bekommt aber nicht die Navigation
  2. Haben Sie die Aktion Empfangs umleiten sofort - Browser Sie sich diese Umleitungen zu verlassen scheinen der Geschichte
  3. Platz ein einzigartiges Token in der Sitzung und auf dem Formular - wenn sie das Formular verarbeiten übereinstimmen - wenn nicht die Form für einen frischen klar einreichen

Gibt es mehr?

Gibt es einige spezifische Implementierungen von diesen?

Ich kann die dritte Option als ActionFilter mit einer HtmlHelper-Erweiterung in ähnlicher Weise wie die Anti-Fälschung Zeug implementiert werden.

Ich freue mich von Ihnen zu hören MVC'ers da draußen.

Antwort

16

Oft übersehen, die meisten herkömmlichen Weg, dies zu handhaben, die nonce Schlüssel zu verwenden ist.

können Sie verwenden PRG wie andere schon erwähnt haben, aber die Kehrseite mit PRG ist, dass es nicht das Doppelklick-Problem nicht lösen, es erfordert eine zusätzliche Fahrt zum Server für die Umleitung, und da der letzte Schritt Bei einer GET-Anfrage haben Sie keinen direkten Zugriff auf die Daten, die gerade gepostet wurden (obwohl sie als Abfrageparameter übergeben oder auf der Serverseite verwaltet werden könnten).

Ich mag die Javascript-Lösung, weil es funktioniert meisten der Zeit.

Nonce Tasten arbeiten jedoch die ganze Zeit. Der Nonce-Schlüssel ist eine zufällige eindeutige GUID, die vom Server generiert (ebenfalls in der Datenbank gespeichert) und in das Formular eingebettet wird. Wenn der Benutzer das Formular anmeldet, wird auch der Nonce-Schlüssel gesendet. Sobald ein POST beim Server eingeht, überprüft der Server, ob der Nonce-Schlüssel in seiner Datenbank vorhanden ist. Wenn dies der Fall ist, löscht der Server den Schlüssel aus der Datenbank und verarbeitet das Formular. Wenn der Benutzer zweimal POST sendet, wird folglich der zweite POST nicht verarbeitet, da der Nonce-Schlüssel nach der Verarbeitung des ersten POST gelöscht wurde.

Der Nonce-Schlüssel hat den zusätzlichen Vorteil, dass er zusätzliche Sicherheit bietet, indem er replay attacks verhindert (ein Mann in der Mitte schnüffelt Ihre HTTP-Anfrage und gibt sie dann dem Server wieder, der sie als legitim behandelt).

+0

Interessante Idee, eine Sache, die ich hinzufügen würde, ist, dass Sie die Sequenz in eine Transaktion setzen sollten: 1) überprüfen Sie nonce 2) Prozess 3) lösche nonce. Wenn du das nicht atomar machst, hast du eine Race Condition, in der der Post mehrere Male verarbeitet werden kann. wenn die Verarbeitung etwas dauert (und der Benutzer ungeduldig ist). Eine Sache, die mir immer noch nicht klar ist, ist, wenn der POST eine doppelte Einreichung erkennt, was sollte dem Benutzer zurückgegeben werden? Eine Seite, die anzeigt, dass der Post in Bearbeitung ist? – DSO

+0

Ich würde zuerst den Nonce-Schlüssel löschen und dann die Verarbeitung durchführen, um die Dinge einfach zu halten. Wie man mit einem Betrogenen umgeht, ist eine Designentscheidung und liegt bei Ihnen. Eine beschreibende Antwort auf das, was gerade passiert ist, würde dem Benutzer jedoch helfen, Ihre Web-App noch mehr zu schätzen. – aleemb

+0

Haben Sie eine Implementierung von Nonce-Schlüsseln in ASP.NET MVC mit ActionFilters vielleicht gesehen? Ich kann mir vorstellen, dass dies die Implementierung sehr einfach und wiederverwendbar machen würde. Es könnte auch eine DB oder einfach eine Sitzungsvariable verwenden. – WooWaaBob

1

Dies ist wirklich nicht MVC-spezifisch, aber das Muster, das wir auf unseren Webseiten verfolgen, besteht darin, dass Aktionen mit AJAX-Aufrufen statt mit Ganzseiten-POSTs ausgeführt werden. Wenn Sie also zu einer URL navigieren, wird keine Aktion ausgeführt, sondern nur das Formular angezeigt. Der AJAX-Anruf ist nicht in der Historie

0

Zusammen mit der Deaktivierung von Schaltflächen können Sie ein transparentes Div über die gesamte Webseite hinzufügen, so dass das Klicken nichts tut. Wir machen dies bei meiner Arbeit und fügen ein kleines freundliches Etikett hinzu, das die Verarbeitungsanforderung sagt.

5

Sie sollten immer eine Weiterleitung als HTTP-Antwort auf einen POST zurückgeben. Dies verhindert, dass der POST erneut auftritt, wenn der Benutzer mit den Vorwärts/Zurück-Schaltflächen im Browser vor- und zurück navigiert.

Wenn Sie sich Sorgen machen, dass Benutzer auf die Schaltfläche "Senden" doppelklicken, lassen Sie sie durch ein kleines Skript sofort beim Senden deaktivieren.

+0

was unsere schöne nicht js Benutzer? – redsquare

+0

Skripte können unaufdringlich sein und auf eine Weise eingefügt werden, die nicht-js Browser/Benutzer nicht stört. Wenn Sie sich immer noch Sorgen über Dual-Form-Eingaben machen, benötigen Sie eine serverseitige Logik, um das zu handhaben. – mookid8000

+0

das ist, was ich bekam. Die Logik ist serverseitig besser implementiert als mit js – redsquare

2

Sie könnten am Post-Redirect-Get (PRG) Muster aussehen wollen:

+1

PRG-Muster löst nicht das Problem, dass der Benutzer mehrmals auf "submit" klickt. – DSO

+0

Nein, tut es nicht - es macht das Zurück-Button Problem lösen, obwohl –

+0

Sie bequem den einen Doppelklick mit einer einfachen JavaScript-Funktion verhindern. – josephdotca

Verwandte Themen