如何防止在 PHP 中多次单击时提交多个表单
Posted
技术标签:
【中文标题】如何防止在 PHP 中多次单击时提交多个表单【英文标题】:How to prevent multiple form submission on multiple clicks in PHP 【发布时间】:2011-06-04 14:01:13 【问题描述】:php中如何防止多次点击提交多个表单
【问题讨论】:
由于问题是关于服务器端行为 (PHP),我建议查看以下问题:***.com/questions/218907/…<input type="submit" onclick="this.disabled='disabled'"/>
javascript 方法是否比自动点击器更快,每秒点击次数 > 1000?
How to handle multiple submissions server-side的可能重复
【参考方案1】:
您也可以通过设置一个独特的字段(例如电子邮件/用户名或注册号)来防止这种情况。然后将新字段与数据库中的现有字段进行测试,如果匹配,则用户之前已注册,表单提交应停止,否则继续提交表单。
【讨论】:
【参考方案2】:我在 action.php 上做如下操作
if($_SESSION && isset($_SESSION['already_submitted']))
# If already submitted just redirect to thank you page
else
# If first submit then assign session value and process the form
$_SESSION['already_submitted'] = true;
# Process form
注意:始终使用 session_start(); 在标头中启动会话
【讨论】:
【参考方案3】:你能隐藏点击按钮吗?它不会影响表单处理(我知道问题在于立即禁用按钮),但它基本上会做同样的事情。如果您真的担心它,您甚至可以只显示另一个实际上不执行任何操作的按钮。可能是一种非常规的解决方法,但仍然是一种解决方法。
【讨论】:
如果用户通过按回车键或应用程序中的某些内置 JavaScript(例如form.submit()
)提交表单怎么办?为确保表单不会同时重新提交两次(或多次),应该有提交的标识符并跟踪它们的完整性。如果您要生成 ID,我建议您使用这个 API (api.cloudianos.com/genToken),它以提供唯一的(用于中短期)int + char 字符串而闻名。【参考方案4】:
我建议不要禁用提交按钮,因为在临时网络问题(即请求根本没有通过)的情况下,如果用户选择中止提交(Esc键/停止按钮),他将无法提交一旦网络服务已恢复,则必须重新加载页面并再次填写所有表单条目。
【讨论】:
【参考方案5】:使用每次显示表单时生成的唯一令牌,并且只能使用一次;防止CSRF 和replay 攻击也很有用。 一个小例子:
<?php
session_start();
/**
* Creates a token usable in a form
* @return string
*/
function getToken()
$token = sha1(mt_rand());
if(!isset($_SESSION['tokens']))
$_SESSION['tokens'] = array($token => 1);
else
$_SESSION['tokens'][$token] = 1;
return $token;
/**
* Check if a token is valid. Removes it from the valid tokens list
* @param string $token The token
* @return bool
*/
function isTokenValid($token)
if(!empty($_SESSION['tokens'][$token]))
unset($_SESSION['tokens'][$token]);
return true;
return false;
// Check if a form has been sent
$postedToken = filter_input(INPUT_POST, 'token');
if(!empty($postedToken))
if(isTokenValid($postedToken))
// Process form
else
// Do something about the error
// Get a token for the form we're displaying
$token = getToken();
?>
<form method="post">
<fieldset>
<input type="hidden" name="token" value="<?php echo $token;?>"/>
<!-- Add form content -->
</fieldset>
</form>
将它与重定向相结合,这样您就可以保持完美的向后和向前行为。 有关重定向的更多信息,请参阅POST / redirect / GET 模式。
【讨论】:
有人知道这段代码有什么问题吗,比如安全问题? 我认为 $postedToken = filter_input(INPUT_POST, 'token'); 上缺少过滤器【参考方案6】:你可以添加这样的东西
<input type="hidden" name="form-token" value="someRandomNumber">
然后在后端,您有一种识别多个表单提交的保存方法。当然,这个解决方案有一些包袱,因为你必须删除你知道已经完成处理的表单令牌等等......
在大多数情况下,禁用的表单可以解决问题,例如通过禁用按钮或将return false
添加到表单提交事件(但不确定在没有 jQuery 的情况下这是否有效)。
【讨论】:
哦,好吧,看来我的回答有点晚了... 支持其他答案【参考方案7】:您可以在第一次点击后禁用按钮(使用 JavaScript),还可以检查后端(以防万一他们禁用了 JavaScript)检查他们是否最近提交。
有很多不同的方法可以在后端进行检查。一种方法是在他们第一次单击时设置会话变量,这可以让系统知道它正在处理。如果他们点击了第二次、第三次或第四次,那么它可以只检查会话变量,如果这表明它已经被点击了,它就不会处理。
这只是一个示例 - 您可以以此为起点。
【讨论】:
以上是关于如何防止在 PHP 中多次单击时提交多个表单的主要内容,如果未能解决你的问题,请参考以下文章