【问题标题】:How to get around the saved $_POST variables in PHP? [duplicate]如何绕过 PHP 中保存的 $_POST 变量? [复制]
【发布时间】:2013-10-23 23:39:30
【问题描述】:

所以基本上,我正在创建一个超小型的批量电子邮件应用程序,供个人使用。

它有一个非常小的表单,仅包含一个 CSV 文件的上传按钮和一个电子邮件主题的下拉列表。每封邮件都取自 CSV 文件,保存在一个数组中,并通过一个循环进行处理和发送。

我只在设置了 $_POST 'submit' 时才运行它。虽然,在页面重新加载/刷新时,由于 $_POST 变量仍然设置/存在,所有电子邮件都在没有按下提交按钮的情况下再次发送。

我会在这里发布我所有的代码,虽然它有点大。如果迫切需要,我可以将其缩短并在此处发布。

有没有办法解决这个问题?

【问题讨论】:

  • Google for nonce's:基本上是一个表单中的隐藏令牌,只能使用一次,并且不会再次执行该操作,因为您的@ 987654322@ 不再有效。所以:创建随机值,添加到会话中,添加为隐藏输入,接收时:在会话中查找它,如果找到则将其删除并采取行动,如果未找到:不要采取行动。
  • @Wrikken - 你能举个例子吗?当前未使用会话。
  • @JohnConde - 不使用 C#,所以这个问题是完全不同的,并要求解决(示例)PHP 中的 $_POST 变量。
  • 发布/重定向/获取与您使用的语言无关。点击我答案中的链接。
  • @fizzix 请参阅我的答案中的“替代方法一”,了解如何使用一次使用的随机数/数字的示例。这里我使用“sha1(rand())”来创建“数字”,它实际上是一个大的随机十六进制字符串,确保你永远不会得到相同的数字,除非你每秒运行数百万次数百年.

标签: php email post csv


【解决方案1】:

这就是 HTTP 协议的设计工作方式,尽管大多数 GUI Web 浏览器会以某种形式警告用户“您确定要重新提交数据吗?”消息。

为了避免这种情况,我们的政策是绝不会在 POST 请求中将任何页面发送回浏览器。我们总是处理数据,然后使用 header('location:') 重定向到显示结果的 GET 请求。

例如:

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

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

基本上这使得用户无法刷新页面,因为刷新将刷新“done.html”而不是 POST 请求。

如果您要发送大量电子邮件,它们可能会在您发送电子邮件时刷新页面。为了解决这个问题,我会采取以下两种方法之一:

替代方法一,使用日志避免重复:

使用 <input type="hidden" name="submit" value="<?php echo sha1(rand()); ?>"> 之类的东西代替“submit=1”

然后,您的 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,并让他们为您处理电子邮件。

【讨论】:

  • 但是如果我需要刷新页面以使用新数据再次用于应用程序怎么办?
  • 然后只需重定向到带有 new 数据的页面。
  • 您的替代方法似乎合乎逻辑,我可能会尝试一下。有没有办法取消设置 $_POST 变量?
  • 虽然,强制页面不刷新并不理想,因为我需要使用不同的 CSV 文件多次运行应用程序...
  • 后变量不会保存在任何地方。它是存储它并在您刷新时再次发送它的网络浏览器。服务器无法告诉浏览器清除它
猜你喜欢
  • 1970-01-01
  • 2015-09-05
  • 2012-03-30
  • 2011-01-26
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 2016-06-29
  • 2020-07-14
相关资源
最近更新 更多