フォームの繰り返し送信の問題を本当に解決する php code_PHP チュートリアル
Jul 13, 2016 am 10:47 AMフォームの重複送信を防ぐための js や jquery プログラムを数多く見てきましたが、これは単なる方法であり、このページからフォームを送信し、データを受け入れるページを直接見つけないと、この js 処理方法は無効になります。以下では、php を使用してそれを解決します。
繰り返し送信を防ぐために以前に使用されていたjsフォームメソッド
コードは次のとおりです | コードをコピー |
<script type="text/javascript"> // 初投稿 //重複送信 //以下の3つのメソッドがそれぞれ呼び出されます <フォーム onsubmit="return checkSubmit();"> <input type="submit" onclick="return checkSubmit(); /> <input type="button" onclick="document.forms[0].action='./test';document.forms[0].submit();return checkSubmit(); /> |
直接フォームを作成して /test に送信すると、上記のエージェントは単なる飾りなので、この問題をどう解決すればよいでしょうか
すでに解決方法を知っている場合は、この記事はあなたの好みに合わないかもしれません。Paperen は基礎から説明するつもりなので、解決策を一気に見たい場合には適さないかもしれません。注目してください。それでは~始めましょう~
フォームとは何かを知っておく必要があると思います。フォーム要素は、Web ページで入力が必要な場所で使用する必要があります。一般的なコードは次のとおりです。
コードをコピー | |
メソッド="投稿"> <p> <label for="test">好きなものを入力してください www.bKjia.c0m</label> <input type="text" name="data" id="test" /> </p> <p> <input type="submit" value="submit" name="submit" /> </p> </ul> </フォーム> |
を使用してこのフォームを送信した後のブラウザのアドレス バーには表示されません。
コードをコピー | |
http://localhost/mytest/token/form.php?data=test&submit=%E6%8F%90%E4%BA%A4
|
コードは次のとおりです | コードをコピー |
<?php If ( isset( $_POST['submit'] ) ) { //フォーム送信処理 $data = isset( $_POST['data'] ) htmlspecialchars( $_POST['data'] ) : ''; //データベースを挿入または更新します $sql = "テスト (`string`) 値に挿入 ('$data')"; //クエリを実行します エコー $sql; } ?> |
ここではデータはポストによって送信されるため、PHP の $_POST グローバル変数を使用して、フォームによって送信されたデータを取得できます。post メソッドを使用してサーバーに送信されたすべてのフォーム データは、この $_POST グローバル変数に保存されます。 print_r($_POST) 変数を試してみると理解できるでしょう。
まず $_POST 配列に submit があるかどうかを確認します。存在する場合は、asp.net に ispostback と呼ばれるものがあるようですが、それほど厳密ではありません。この問題は後で解決します。
入力ボックスでデータを受け取った後、それは $_POST['data'] です。HTML タグや JavaScript の入力によって引き起こされる問題を防ぐために、これに対して htmlspecialchars を使用して HTML フィルタリングを実行することを忘れないでください。 XSS の脆弱性)。最後に、SQL ステートメントに結合され、実行のためにデータベースに送信されます (mysql_query など、ここでデータベースを詳細に操作するための一部の関数を Paperen が使用していないだけなので、自分で完成させることに興味があります) 。おめでとうございます。これでデータ入力機能は正常に完了しました。ただし、データを挿入した後、オペレーターにプロンプトを表示する必要があるため、改善する必要があります。少なくとも、操作が失敗したか成功したかを確認するようにしてください。したがって、コード全体は次のように記述されます。
コードは次のとおりです | コードをコピー |
<?php <?php if ( isset( $state ) && $state ) { //データは正常に挿入されましたか?> <p>正常に挿入されました <a href="form.php">戻る</a></p> <?php } else { //失敗したか、アクションが挿入されませんでした ?> <フォームメソッド="post"> <p> <label for="test">必要なものを入力</label> <input type="text" name="データ" id="テスト" /> </p> <p> <input type="submit" value="submit" name="submit" /> </p> </ul> </form> <?php } ?> |
最初のコードと比較すると、html の宣言と head と body が省略されています。実際には、実際のデータベースへの挿入と操作のフィードバック ($state 変数を介して) を実現します。コードを自分でコピーして、試してみてください(もちろんデータベース操作部分のコードは実際の状況に合わせて修正してください)。コードは正常でロジックも問題ありませんが、問題があります。つまり、挿入が成功したことを表示した後にページを更新すると、フォーム処理アクションが再度実行され、データが再度挿入されます。これは重複挿入問題と呼ばれます。ソリューションをリリースする前に、自分で解決する方法を考えることができます。
この問題は、このページでデータを受信して処理結果を表示することが原因だと思いますか?はい、いくつかのデバッグ ツールを使用すると、ブラウザにも投稿データが保持されることがわかり、送信後にフォームを更新すると、投稿データが再送信されます。
ブラウザに一時的に保存された投稿データをクリアする方法があれば問題は解決しますが、これはブラウザ独自のものであるため、サーバーはこれを行うことができません。そうしないと、再度更新しても送信されます。データを繰り返し実行します。
ここまでで、繰り返し送信の意味と問題の深刻さを理解できたかもしれません。リダイレクト方法を選択しない場合は、別の方法を考える必要があるため、これがトークンの解決策です。
トークン自体が権限、操作権限、アイデンティティフラグなどを表すのと同じように、クライアントがこのフォームをリクエストするたびに、そのようなアイデンティティフラグをフォームに追加して、同時にトークンフックを生成できますか?正しい場合は、フォームを受信して処理します。実装の本質はこんな感じで、これを具体的な実装に反映させるにはセッションと呼ばれるものを使う必要があります。セッション分析については、wiki を参照してください
簡単に理解すると、セッションもトークンの概念なので、「トークンを何に使ったんだ?!」と驚かれるかもしれませんが、私たちが達成したいのはセッションだけではなく、その基盤です。達成するためにいくつかのデータを添付します。必要なフォームトークン。それでは、やってみましょう!
セッションは PHP のスーパーグローバル変数 $_SESSION にも保存されます。これを有効にするには session_start() を使用してください。原理は他のサーバーサイド スクリプトでも同じですが、呼び出しメソッド名が一致しない可能性があります。トークンを追加した後のコードは次のとおりです:
コードは次のとおりです | コードをコピー |
<?php //オープンセッション Session_start(); If ( isset( $_POST['submit'] ) && valid_token() ) { //フォーム 処理のために送信します } /** * トークンを生成します * @return string MD5 暗号化タイムスタンプ */ 関数 create_token() { //現在のタイムスタンプ $timestamp = time(); $_SESSION['トークン'] = $タイムスタンプ; md5( $timestamp ); を返します } /** * トークンは有効ですか? * @return bool */ 関数 valid_token() { If ( isset( $_SESSION['token'] ) && isset( $_POST['token'] ) && $_POST['token'] == md5( $_SESSION['トークン'] ) ) { // 正しい場合、このトークンは破棄されます $_SESSION['トークン'] = ''; true を返します; } false を返します; } ?> <?php if ( isset( $state ) && $state ) { //データは正常に挿入されました?> <p>正常に挿入されました <a href="form.php">戻る </a></p> <?php } else { //失敗したか、挿入アクションがありませんか?> <フォームメソッド="投稿"> <p> <label for="test">何でも 何かを入力してください</label> <input type="text" name="data" id="test" /> </p> <p> <input type="submit" value="Ti " 送信" name="送信" /> </p> </ul> <!-- トークン --> <input type="hidden" value="<?php echo create_token(); //生成 トークン ?>" name="トークン" /> <!-- トークン --> </フォーム> <?php } ?> |
コードをコピー | |
<?php if ( !定義('BASEPATH')) exit('直接スクリプトアクセスは許可されません'); クラス Welcome extends CI_Controller {
パブリック関数index()
{
$token = $this->form_validation->create_token();
echo form_open(); |
コードは次のとおりです | コードをコピー |
<?php if ( !定義('BASEPATH')) exit('直接スクリプトアクセスは許可されません'); /** /** /** パブリック関数__construct() /** /** /** // 送信されたハッシュ if ( md5( $source_hash ) == $post_formhash ) /** |

人気の記事

人気の記事

ホットな記事タグ

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法
