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;
}

基本上这使得用户无法刷新页面,因为刷新将刷新“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 并让他们为您处理电子邮件。

于 2013-10-23T23:44:43.530 回答