4

ユーザーが[戻る]ボタンを押したときにフォームが再処理されないようにするための最良の方法は何ですか?

Post / Redirect / Getパターンに従っているので、F5を押しても問題はありませんが、戻るボタンを押すとフォームを再送信できます。このフォームがクレジットカード処理ページの場合、これは悪いことです。

この質問はここでいくらか尋ねられましたが、言い回しと答えは質が低く、この問題に正確に固有のものではありませんでした。

私は自分自身に提出するform.phpを持っています。送信時に入力データにエラーがなかった場合、ユーザーはform_thanks.phpにリダイレクトされます。一度ヒットバック(および「送信」または「再送信」)すると、form.php(BAD!)が再送信され、form_thanks.phpに戻されます。

可能であれば、セッションの使用を伴わないソリューションも含めてください。

4

6 に答える 6

7

私はそれを別の方法で行います。値としてランダムな文字列を使用して非表示の入力を設定し、送信されたときにそのランダムな文字列をセッションに保存します。簡単なチェックを設定して、投稿済みかどうか、入力を受け入れていないかどうかを確認します。

于 2009-10-29T23:07:16.843 に答える
2

これは、使い捨てトークンまたはナンスを使用して実行する必要があります。php / serverは、このトークンを非表示のフォームフィールドに含める必要があります。

最近のすべてのトークンのリストを保存する必要があり、フォームが送信されるたびに、トークンが最近の有効なトークンのリストに含まれているかどうかを確認する必要があります。

リストにない場合は、フォームを再処理しないでください。
リストにある場合は、フォームを処理して、トークンをリストから削除します。

トークンは、セッション内で処理することも、セッションのない単純なデータベーステーブルで処理することもできます。ただし、トークンはユーザー固有である必要があります。

これは、 CSRF攻撃を回避するための推奨される方法でもあります。

于 2009-11-02T17:06:25.773 に答える
1

遅い答えですが、AJAXベースのソリューションを使用することで処理を完全に回避することができます。この処理スキームにナンスを含めることに問題はありませんが、成功するとユーザーをリダイレクトする非同期クエリを使用することにより、更新、押し戻す、またはボタンをクリックする以外の方法で要求が繰り返されることはありません。

また、リクエストのハンドラーに埋め込むことで、リクエスト中に何かが発生した場合にボタンが2回押されたり、「ロックアップ」されたりするのを防ぐメカニズムを実装するのも簡単です(PrototypeJSまたはjQueryの高レベル、またはハンドロール機能)リクエストが完了したときと最初に起動したときにボタンを有効または無効にするメカニズム。

于 2009-11-17T20:58:25.753 に答える
1

ここで大声で考えてください。しかし、最終的な取得が実際には最終的な取得ではないpost / redirect / getのバリエーションについてはどうでしょうか;)むしろ、常に自動的に最終的なページに転送されるため、ユーザーが戻るボタンを押すと、彼らが来たのはどこからですか?

編集:

さて、OPのコメントを考慮して、ここに別のアイデアがあります。フォーム送信のURLは、1回の使用にのみ適したパラメーターを要求するように作成できます。そのトークンは、フォームが送信される前に(MD5などを使用して)生成され、データベースに保存できます(セッションを使用せずに解決策を要求した他の誰かの提案に応えて)。フォームが処理された後、このトークンはデータベースですでに使用されているというフラグが立てられます。同じトークンでページに戻ったときに、フォームデータがバックエンドに再送信されないようにするための手順を実行できるようにします。

于 2009-10-29T23:33:43.950 に答える
0

ページがリダイレクトされる前の状態にフォームが戻ることがわかりました。その場合は、入力/変数が非表示になっているか、値で始まるものがtrueと表示され、フォームが送信されると、値がtrueの場合は、falseに変更してから送信します。それ以外の場合は、falseを返します。

于 2009-10-29T22:06:31.660 に答える
-1

これを試して :

<SCRIPT type="text/javascript">
    window.history.forward();
</SCRIPT>
于 2012-10-02T06:16:00.007 に答える