ユーザーがフォームを送信すると、ネットワーク速度のせいで同じレコードが繰り返しデータベースに挿入される可能性があります。または、Web ページが悪意をもって更新される可能性があります。これは難しい問題です。同じフォームを繰り返し送信することを避けるために、クライアント側とサーバー側から同時に開始することができます。
1.クライアント側スクリプトの使用
クライアント側スクリプトに関しては、一般的な入力検証に JavaScript がよく使用されます。次の例では、フォームの繰り返し送信を処理するためにこれを使用しています。以下のコードを参照してください:
ユーザーが「送信」ボタンをクリックすると、図 5-6 に示すように、ボタンが灰色になり使用できなくなります。
上記の例では、OnClick イベントを使用してユーザーの送信ステータスが検出され、「送信」ボタンがクリックされると、ボタンはすぐに無効な状態に設定され、ユーザーはボタンをクリックして再度送信できなくなります。 。
これも JavaScript の関数を使用しますが、フォームが一度送信されると、すぐにダイアログ ボックスが表示されます。コードは次のとおりです。 ;script language=”javascript” >
var submitcount=0;
function submitOnce (form){
if (submitcount == 0){
submitcount++;
return true;
} else{
alert (「動作中です。再送信しないでください。ありがとうございます!」);
return false;
}
}
//–>
上記の例では、ユーザーが「送信」ボタンをクリックした場合、スクリプトは現在のステータスが自動的に記録され、submitcount 変数が 1 ずつ増加します。ユーザーが再度送信しようとすると、スクリプトは submitcount 変数の値が 0 以外であると判断し、フォームが送信されたことをユーザーに通知するため、繰り返しの送信が回避されます。フォームの。
2. Cookie 処理を使用します
Cookie を使用してフォームの送信ステータスを記録します。次のコードを参照してください。
if( $_POST['go'] )){
setcookie("tempcookie","",time()+30);
header("Location:".$_SERVER[PHP_SELF]);
exit();
}
if(isset($_COOKIE["tempcookie"])){
setcookie("tempcookie","",0);
echo "すでにフォームを送信しています";
}
?>
クライアントが Cookie を無効にしている場合、このメソッドは効果がありませんので、注意してください。 Cookie の詳細については、第 10 章「PHP セッション管理」を参照してください。
3.セッション処理を使用する
PHPのセッション関数を使用すると、フォームの繰り返しの送信を回避することもできます。セッションはサーバー側に保存され、次回この変数にアクセスすると、セッション変数を使用して送信された値を記録できます。フォームが一致しない場合は、ユーザーが再送信しているとみなされます。次のコードを参照してください:
session_start();
//現在の SESSION に基づいて乱数を生成します
$code = mt_rand(0,1000000);
$ _SESSION['code'] = $code;
?>
ページフォームの隠し値として乱数を渡します。コードは次のとおりです:
”>
受信ページのPHPコードは次のとおりです:
< ?php
session_start();
if(isset($_POST['originator '])) {
if($_POST['originator'] == $_SESSION['code']){
//フォームを処理するステートメント。
}else{
echo を省略します。このページを更新したり、フォームを再度送信したりしないでください。 ’;
}
}
?>
4.ヘッダー関数を使ってリダイレクトします
上記の方法に加えて、より簡単な方法があります。つまり、ユーザーがフォームを送信すると、サーバー側でそれを処理し、すぐに他のページにリダイレクトします。 コードは次のとおりです。
if (isset($_POST['action']) && $_POST['action'] == 'submitted') {
//データ挿入後などのデータを処理し、すぐに他のページにリダイレクトします
header ( 'location:submits_success.php');
}
このようにすると、ユーザーが更新キーを使用した場合でも、フォームは新しいページにリダイレクトされるため、繰り返し送信されることはありません。そして、このページ スクリプトは送信データを無視しました。
5. フォームの有効期限の扱い
開発プロセス中に、フォームエラーが発生し、ページに戻ったときに入力されたすべての情報が失われることがよくあります。これは、ページバウンスをサポートするために、次の 2 つの方法で実現できます。
5.1 ヘッダ header を使用してキャッシュ制御ヘッダ Cache-control を設定します。
header(‘Cache-control: private, must-revalidate’); // ページバウンスをサポート
5.2 session_cache_limiter メソッドを使用します。
session_cache_limiter('private,must-revalidate'); // session_start メソッドの前に記述されます
次のコード スニペットは、ユーザーがフォームに入力して「送信」ボタンをクリックして戻ることを防ぐことができます。フォーム上で入力された内容はクリアされません:
session_cache_limiter('nocache');
session_cache_limiter('private');
session_cache_limiter('public');
session_start();
//以下はフォームの内容です。ユーザーがフォームに戻ったときに、入力した内容はクリアされません
このコードをスクリプトの先頭に貼り付けるだけで適用されます。
Cache-Control メッセージ ヘッダー フィールドの説明
Cache-Control は、リクエストと応答が後に続くキャッシュ メカニズムを指定します。要求メッセージまたは応答メッセージで Cache-Control を設定しても、別のメッセージの処理中のキャッシュ プロセスは変更されません。
リクエスト中のキャッシュ命令には、no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached が含まれます。応答メッセージ内の命令には、public、private、no- が含まれます。キャッシュ、ストアなし、変換なし、必須再検証、プロキシ再検証、および最大有効期間。各メッセージ内の命令の意味は次の表に示すとおりです。
キャッシュ命令
は
を示します
public
は応答を任意のキャッシュでキャッシュできることを示します
private
は示します単一ユーザーの場合、応答メッセージ全体または一部を共有キャッシュで処理することはできません。これにより、サーバーは、ユーザーの部分的な応答メッセージが他のユーザーのリクエストに対して無効である場合にのみ記述することができます。
no-cache
は、リクエストまたは応答メッセージをキャッシュできないことを示します。重要な情報が意図せずに公開されることを防ぐために使用されます。リクエスト メッセージを送信すると、リクエスト メッセージとレスポンス メッセージの両方でキャッシュが使用されます
max-age
クライアントが秒単位で指定された時間を超えない有効期間のレスポンスを受信できることを示します
min-fresh
クライアントが、現在時刻に指定された時間を加えた時間よりも短い応答時間で応答を受信できることを示します。
max-stale
クライアントがタイムアウト期間を超える応答メッセージを受信できることを示します。 max-stale メッセージの値が指定されている場合、クライアントはタイムアウト期間の指定値を超える応答メッセージを受信できます
セッションと Cookie の概要については、第 10 章「PHP セッション管理」を参照してください。詳細。
フォームのアクションを判断するためのテクニック
フォームには同じプログラムで処理されるべきアクションを割り当てることができます。ユーザーが押したボタンの内容をどのように判断するかは小さな問題です。
実際、フォームが送信されると、押された送信タイプのボタンのみがフォーム配列に送信されるため、ボタンの値を判断するだけで済みます。ユーザーがどのボタンを押すかを例として挙げます:
ユーザーが「a」ボタンを押したときbtn=aの場合は「b」ボタンを押し、btn=bを押してください。
送信ボタンの名前で判断することもできます。次のコードを参照してください:
このように、パラメータさえあれば、 POST/GETのaやbがあればどのボタンが押されたのかがわかります。
print_r($_POST);
?>