1

基本的に、私は個人用の超小型の一括メールアプリケーションを作成しています。

CSV ファイルのアップロード ボタンと、メールの件名のドロップダウン リストのみで構成される非常に小さなフォームです。各電子メールは CSV ファイルから取得され、配列に保存され、ループを通過して処理および送信されます。

$_POST 'submit' が設定されている場合にのみ、これを実行しています。ただし、ページの再読み込み/更新時に、 $_POST 変数がまだ設定/存在しているため、送信ボタンを押さなくてもすべてのメールが再送信されます。

少し大きいですが、すべてのコードをここに投稿します。どうしても必要な場合は、短くしてここに投稿できるかもしれません。

これを回避する方法はありますか?

4

1 に答える 1

2

これは、HTTP プロトコルが機能するように設計されている方法ですが、ほとんどの GUI Web ブラウザーは、ユーザーに何らかの「データを再送信しますか?」という警告を表示します。メッセージ。

このような状況を回避するために、私たちのポリシーは、POST 要求でページをブラウザに送り返さないことです。常にデータを処理してから、header('location:') を使用して結果を表示する GET リクエストにリダイレクトします。

例えば:

if (isset($_POST['submit']) {
 /* process post data */

  header('Location: done.html');
  exit;
}

基本的に、これによりユーザーはページを更新できなくなります。更新すると、POST 要求ではなく "done.html" が更新されるためです。

ただし、大量のメールを送信している場合は、メールの送信中にページが更新されることがあります。それを解決するには、次の 2 つの方法のいずれかを使用します。

代替アプローチ 1、ログを使用して重複を回避します。

「submit=1」の代わりに次のようなものを使用します<input type="hidden" name="submit" value="<?php echo sha1(rand()); ?>">

次に、php スクリプトは値を記録し、それが 2 回使用されると文句を言います。

if (file_exists('./'.$_POST['submit'])) {
  die('do not refresh!');
}
file_put_contents('./'.$_POST['submit'], '1'); // TODO: make sure a hacker doesn't put a different path in 'submit' allowing them to write to your server's filesystem... just check if there are any '/' characters in $_POST['submit']

別のアプローチ 2:

「送信済み」ブール値を使用して、mysql データベースに送信する必要があるすべての電子メールを保存します。メールを送信するたびに、そのブール値を true に設定します。ブール値が false である電子メールを送信しないでください。これは手間がかかりますが、安定したシステムの構築に時間を費やしても構わないと思っている場合は、メールの重複で顧客を困らせないようにするのが「適切な」アプローチです。

おそらく、このアプローチを使用するよりも良いアイデアは、MailChimp などの無料サービスにサインアップして、メールを送信してもらうことです。

于 2013-10-23T23:44:43.530 に答える