这就是 HTTP 协议的设计工作方式,尽管大多数 GUI Web 浏览器会以某种形式警告用户“您确定要重新提交数据吗?” 信息。
为了避免这种情况,我们的策略是永远不会在 POST 请求中将任何页面发送回浏览器。我们总是处理数据,然后使用 header('location:') 重定向到显示结果的 GET 请求。
例如:
if (isset($_POST['submit']) {
/* process post data */
header('Location: done.html');
exit;
}
基本上这使得用户无法刷新页面,因为刷新将刷新“done.html”而不是 POST 请求。
但是,如果您要发送大量电子邮件,它们可能会在您发送电子邮件时刷新页面。为了解决这个问题,我将采用以下两种方法之一:
替代方法一,使用日志避免重复:
而不是“提交= 1”使用类似<input type="hidden" name="submit" value="<?php echo sha1(rand()); ?>">
然后,您的 php 脚本会记录该值并在它被使用两次时抱怨:
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']
替代方法二:
使用“已发送”布尔值保存您需要发送到 mysql 数据库的每封电子邮件。当您发送每封电子邮件时,该布尔值设置为 true。永远不要发送布尔值为假的电子邮件。这是更多的工作,但如果您愿意花时间构建一个稳定的系统,您需要确保您永远不会因重复的电子邮件而惹恼您的客户,那么这是“正确”的方法。
可能比使用这种方法更好的主意是注册免费服务,例如 MailChimp 并让他们为您处理电子邮件。