質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

1575閲覧

二重投稿を阻止するために、htmlを書き換えるかphpで制御したい。

退会済みユーザー

退会済みユーザー

総合スコア0

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2021/07/21 13:34

編集2021/07/22 08:48

前提・実現したいこと

PHP(7.x系)で掲示板システムを作っています。
投稿ボタンを押した後リロードや戻るボタンを押してしまい、二重投稿になってしまうことがありました。
そのため、投稿ボタンにリダイレクトをする文を記述しました。
ですが、うまくいかず、2回戻るボタンを押すと二重投稿ができてしまいます。
誰か知恵を貸してくれる人はいませんか?また、どう書き換えればいいか教えてください。

コード

PHP

1 2<?php 3// recaptchaを使うので、試してみるために組んでいます。 4// よって、使わない部分が多いです。 5// ほぼ確認用のコードです。 6require '../recaptcha/recaptcha_vars.php'; 7// サイトキー 8$siteKey = V2_SITEKEY; 9// シークレットキー 10$secretKey = V2_SECRETKEY; 11$result_status = ''; // 結果を初期化 12if ( isset( $_POST[ 'g-recaptcha-response' ] ) ) { 13//GoogleのAPIを指定 14$url = 'https://www.google.com/recaptcha/api/siteverify'; 15//パラメータを指定 16$data = array( 17'secret' => $secretKey, 18'response' => $_POST[ 'g-recaptcha-response' ] 19); 20//POST メソッドを使用 21$context = array( 22'http' => array( 23'method' => 'POST', 24'header' => implode("\r\n", array('Content-Type: application/x-www-form-urlencoded',)), 25'content' => http_build_query($data) 26) 27); 28//設定したパラメータからAPIを使って取得する 29$api_response = file_get_contents($url, false, stream_context_create($context)); 30$result = json_decode( $api_response ); 31if ( $result->success ) { 32$result_status = '成功しました'; 33//デバッグ用。使わないのでコメントアウト。 34//$re = 'OK'; 35} else { 36$result_status = '失敗しました。: '; 37$result_status .= $result->{'error-codes'}[ 0 ]; 38//デバッグ用。使わないのでコメントアウト。 39//$re = 'NG'; 40} 41} 42print($re); 43?> 44<html> 45<script> 46var onloadCallback = function() { 47grecaptcha.render('recaptcha', { 48'sitekey' : "<?php echo $siteKey; ?>", 49'callback' : verifyCallback, 50'expired-callback' : expiredCallback 51}); 52}; 53var verifyCallback = function(response) { 54document.getElementById("warning").textContent = ''; 55document.getElementById("send").disabled = false; 56}; 57var expiredCallback = function() { 58document.getElementById("warning").textContent = '投稿するにはチェックを入れてください。'; 59document.getElementById("send").disabled = true; 60}; 61</script> 62</head> 63<head> 64<link rel="icon" type="image/png" href="../icon.png"> 65<title>掲示板</title></head> 66<body> 67<body bgcolor="#181a19" text="#cccccc" alink="#ffffff"> 68<p><h1>掲示板</h1></p><br> 69<a href="https://***.**/">***.**(トップページ)</a><br> 70<p>テスト的な意味もありますが、ちょっと作ってみました。</p> 71削除・変更の依頼は<a href="./delete.php" target="_blank">こちら</a>から 72<form method="POST" action="<?php print($_SERVER['PHP_SELF']) ?>"> 73<input type="text" name="personal_name"><br><br> 74<textarea name="contents" rows="8" cols="40"></textarea><br><br> 75<div id="recaptcha"></div> 76<p id="warning">投稿するにはチェックを入れてください。</p> 77<input id="send" type="submit" name="btn1" class="btn btn-primary" disabled value="投稿!!" onclick="location.href='***.**/keiji/keiji_all.php'"> 78</form> 79<?php 80if($_SERVER["REQUEST_METHOD"] == "POST"){ 81writeData(); 82} 83// ファイルを読み込んで表示 84readData(); 85function readData(){ 86$keijban_file = 'keiji_all.txt'; 87$fp = fopen($keijban_file, 'rb'); 88if ($fp){ 89// ファイルロック 90if (flock($fp, LOCK_SH)){ 91while (!feof($fp)) { 92$buffer = fgets($fp); 93print($buffer); 94} 95flock($fp, LOCK_UN); 96}else{ 97// できないなら 98print('ファイルロックに失敗しました'); 99print('何度も失敗する場合は知らせてください。'); 100} 101} 102fclose($fp); 103} 104function writeData(){ 105$personal_name = $_POST['personal_name']; 106$contents = $_POST['contents']; 107$contents = nl2br($contents); 108// HTMLの構成 109$data = "<hr>\r\n"; 110$data = $data."<p>投稿者:".$personal_name."</p>\r\n"; 111$data = $data."<p>内容:</p>\r\n"; 112$data = $data."<p>".$contents."</p>\r\n"; 113// ファイルへ書き込み開始 114$keijban_file = 'keiji_all.txt'; 115$fp = fopen($keijban_file, 'ab'); 116if ($fp){ 117if (flock($fp, LOCK_EX)){ 118if (fwrite($fp, $data) === FALSE){ 119print('ファイル書き込みに失敗しました'); 120print('何度も失敗する場合は知らせてください。'); 121} 122// ファイルロック解除 123flock($fp, LOCK_UN); 124}else{ 125print('ファイルロックに失敗しました'); 126print('何度も失敗する場合は知らせてください。'); 127} 128} 129fclose($fp); 130} 131?> 132</body> 133<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script> 134</html> 135

試したこと

cookieとjavascriptを使ってエラーメッセージを出すようにし、リダイレクトさせる
→どちらか一方を拒否されていると機能しない。
上記のように、リダイレクトさせる
→上記のような問題が発生する

補足情報

PHPバージョンはPHP7.3です。
windows 10のedgeを使って検証しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/07/22 01:33

コードこれだけだと再現確認無理では。 あまり省略されると全体の流れが見えなくなるので、「現象が再現する最小構成のコード」を提示してください。 提示のコードではそもそもエラーとなります。
m.ts10806

2021/07/22 01:34

>windows 10のIE8 >windows XPのIE6でも検証。 そもそもIEが終わるのでここら辺は全然捨てていい範囲かと。
guest

回答2

0

さいきょうの二重サブミット対策
二重投稿の質問が出たときに分かりやすいのでよく引用するのですが、随分時代遅れな記事になってしまいました^^;

記事の「二重サブミットが発生するケース」は非常に分かりやすいと思います。
記事中では対策の「どれか」を選択して使用するように読めますが、実際には複数を組み合わせて使用っするケースが多いです。

投稿2021/07/21 21:42

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ockeghem

2021/07/22 02:09

「時代遅れ」と思われるポイントはどのへんでしょうか? (異論ではなく単なる質問です) 記事をざっと読んだところ、不正確な箇所(例えば「X-Requested-Withでサイトに脆弱性がない場合は大丈夫そうですが、XSSの脆弱性があるとそこを突いて不正更新リクエストを送ることができます。したがって可能であればトークンによる対策と併用した方がよいでしょう」は間違い)はいくつかありそうですが、たとえば、SPAではなく古典的なマルチページのアプリケーションを前提にしているところでしょうか?
退会済みユーザー

退会済みユーザー

2021/07/23 01:12

この質問は「double submit がどうして発生しているのかよく理解できていない」と判断して回答を作りました。 紹介した記事は、私がプログラミングを始めた頃に読んで理解が進んだ記事なので、記事の前半の「二重サブミットが発生するケース」の図は理解しやすいと思います。 ただ、それ以外の箇所で、現在のトレンドにおいては不足してきている情報が多くなったとも思ってます。 特に、記事の後半の「APIによる更新」は、内容が薄く理解が怪しい記事になってしまっています。 当時は記事にある程度の薄い理解でよかった気もしますが、今は画面遷移を伴わない投稿も多くなっているので、「さいきょう」を名乗るには情報不足かと。 また、網羅性観点から DB 内の重複確認の手法に全く触れていない点が残念です。これは当時はあまりやらなかったと思うので仕方ない気もしますが。 後、読み返してみると「CSRF対策」が同一の文脈で語られているのに違和感がありますね。 新しい記事を探さなければいけない時が来たのかもしれないですw
ockeghem

2021/07/24 01:41

回答ありがとうございます。確かにAPIの箇所は全然駄目ですね。APIの場合、二重投稿は避けにくいところがあるので、twitterのように、短期間に同内容の投稿をするとエラーにする(重複確認とも言える)などの手法が考えられますが、記事の「EV SSL証明書を使う」、「APIキーによる利用制限と不正利用の監視」は的外れですね。
guest

0

ベストアンサー

この手の対応方法は色々あってネットで情報漁れば色々出てくると思いますが、ワンタイムトークン的なものを利用するのが有効かと思います。

参考)
https://techacademy.jp/magazine/41842

色々な実装方法があると思うので、参考サイトに出てくる単語を使って色々検索してみてください。

投稿2021/07/21 14:44

AbeTakashi

総合スコア4466

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/07/25 08:39

ありがとうございます。 こちらの方法でできました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問