Php 如何防止用户重新发送表单数据?
我得到了一个Php 如何防止用户重新发送表单数据?,php,forms,Php,Forms,我得到了一个POST表单,它确实会将数据发送到同一个文件中,如果使用浏览器中的“后退”按钮,他可以轻松地重新发送数据,数据仍然会被读取 有什么方法可以避免这种行为吗?如果用户想这样做,你不能100%地防止这种情况发生,但是为了避免意外发生这种情况,请仔细查看。发送表单时,将一个随机数推入$\u会话['stopdupe']值,并放入一个隐藏字段 收到表格进行处理时: 检查$\u会话['stopdupe']是否存在,并与隐藏字段的值匹配。(如果不是,请忽略此帖子) 取消设置$\u会话['stopdu
POST
表单,它确实会将数据发送到同一个文件中,如果使用浏览器中的“后退”按钮,他可以轻松地重新发送数据,数据仍然会被读取
有什么方法可以避免这种行为吗?如果用户想这样做,你不能100%地防止这种情况发生,但是为了避免意外发生这种情况,请仔细查看。发送表单时,将一个随机数推入
$\u会话['stopdupe']
值,并放入一个隐藏字段
收到表格进行处理时:
$\u会话['stopdupe']
是否存在,并与隐藏字段的值匹配。(如果不是,请忽略此帖子)$\u会话['stopdupe']
另一个有用的技巧是使用表单上的
onSubmit
javascript事件来禁用按钮,这样用户就不容易多次提交按钮。Levi发送的链接将为您解答。但如果你想要另一种选择,我会这样做
用户发布到类,如您的。相同的文件。在课程开始时,我做后期处理。对于这个例子,我将使它非常简单
<?php
session_start();
//set form vars ahead of time so you can pre-populate the value attr on post
$form = array(
'name' => '',
'email' => ''
);
if(!empty($_POST))
{
//do some kind of validation...
$errors = array();
if(trim($_POST['name']) == '')
$errors[] = 'Please enter your name';
if(empty($errors))
{
$_SESSION['message'] = 'Thank you for participating';
header('location: /form.php'); // same file
exit;
}
else
{
// set the form vars to the post vars so you don't lose the user's input
$form['name'] = $_POST['name'];
$form['email'] = $_POST['email'];
$message = '<span style="color:red">';
foreach($errors AS $error)
{
$message .= $error."<br />";
}
$message .= '</span>';
$_SESSION['message'] = $message;
}
}
if(isset($_SESSION['message']))
{
echo $_SESSION['message'];
unset($_SESSION['message']);
}
?>
<form id="some_form" action="" method="post">
<fieldset>
<label for="name">Name</label> <input type="text" name="name" value="<?php echo $form['name']; ?>" />
<br /><br />
<label for="email">Email</label> <input type="text" name="email" value="<?php echo $form['email']; ?>" />
<br /><br />
<input type="submit" name="submit" value="Submit" />
</fieldset>
</form>
这个名字对我有用。我使用smarty,但也可以不用smarty。这只是一个想法。根据需要修改它
HTML表单:
<form action="submit_file.php" method="POST">
<input type="hidden" name="submit_edit" value="1">
<input type="text" name="data"/>
</form>
在第一页中,使用一个会话变量并将值赋给1。例如:
<form name="frm1" method="post">
<?php $_SESSION['resend_chk']=1; ?>
<input type="text" name="a" />
<input type="submit" name="submit">
</form>
它将在数据库中插入一次或事务将发生一次,会话变量的值将更改,下次我们尝试重新发送数据时,它将不会执行任何事务,因为会话变量的值已更改。有两种通用方法
后置获取
首先是post redirect get
模式,用户在signup.php
上填写表单,该模式将post
发送到submit.php
,成功完成后将redirect
发送回谢谢.php
。浏览器会看到重定向响应,并发出一个GET forThank.php
。这是因为在没有重定向的情况下,点击refresh将重新加载submit.php
,导致重新发布表单数据警告,并双重发出post
请求。重定向解决了这个问题
signup.php
-----------
...
<input type="text" name="email">
...
submit.php
----------
...
if ($_POST) {
// process data
header('Location: thanks.php');
}
...
thanks.php
----------
...
Thanks
...
服务器需要跟踪所有的nonce密钥问题(在数据库或其他地方),当它收到表单时,它将处理表单并从数据库中删除nonce密钥。如果用户再次提交表单,nonce键将不存在,服务器可以通过忽略或发出警告来处理此问题。这不是完全重复的,但答案是相同的:@LeviMorrison Yea,我以前搜索过一点,找到了相同的,但我真的不知道该怎么做才能得到公认的答案。@LeviMorrison你能告诉我你为什么贬低我的问题吗?@Cyclone可能是因为这个问题以前在这里得到了回答(我猜是他的意见,而不是我的意见)。可能与它所关注的人重复:如果你否决我的答案,请告诉我为什么这样我才能提高。好吧,不是同一个人否决了这个问题,因为是我。@LeviMorrison你不应该贬低我的问题!我敢打赌,被否决的人(不是我)是因为强烈使用了“不能100%阻止这件事”,也许你在读这篇文章时会说没有办法,而不是真的读这篇文章。请注意,这可能会让同一个网站的两个标签同时打开而无法工作。这是真的,@middus。更完整的解决方案是将一个随机值推送到$\u会话['stopdupe']
数组和隐藏字段中,然后在post上检查并从数组中删除该值。这听起来非常聪明!难怪你称自己为MrTrick;)。很好:)谢谢,但它省钱吗?:it’我对安全不太了解。你是说安全吗?让我们这样说吧——浏览器窗口是一个单独的进程。一页一页。$\u POST操作将使用POST数据重新加载页面-这就是我们的脚本所在。一旦它到达该标题行,它就会终止该进程并加载新页面,该页面不会传递任何post数据。你应该非常安全。哦,还有一件事:如果我想检查$\u帖子中的错误,然后显示它们呢?我不能这样做,因为标头会破坏整个输出。只有在验证是干净的情况下,才能转到标头路径。如果没有,则按预期加载页面,除了用post变量预填充表单,这样用户就不会生气,也不会显示错误,不管您选择什么。。。我将修改答案以反映这一点。。。
require_once("globals.php");
if(isset($_POST['submit_edit']) && $_POST['submit_edit'] == '1')){
//record data
}
$oSmarty->dysplay(some.tpl);//in some.tpl is included head.tpl
<form name="frm1" method="post">
<?php $_SESSION['resend_chk']=1; ?>
<input type="text" name="a" />
<input type="submit" name="submit">
</form>
if(isset($_REQUEST['submit'])
{
if($_SESSION['resend_chk']==1)
{
insert to db OR and any transaction
$_SESSION['resend_chk']=0;
}
}
signup.php
-----------
...
<input type="text" name="email">
...
submit.php
----------
...
if ($_POST) {
// process data
header('Location: thanks.php');
}
...
thanks.php
----------
...
Thanks
...
<input type="nonce" value="<?= uniqid(); ?>">