Php 避免由于页面刷新而提交的最佳方法
我认为这个问题经常发生在web应用程序开发中。但我会尽量详细解释我的问题 我想知道如何纠正这种行为,例如,当我有这样一块代码时:Php 避免由于页面刷新而提交的最佳方法,php,html,forms,Php,Html,Forms,我认为这个问题经常发生在web应用程序开发中。但我会尽量详细解释我的问题 我想知道如何纠正这种行为,例如,当我有这样一块代码时: <? if (isset($_POST['name'])) { ... operation on database, like to insert $_POST['name'] in a table ... echo "Operation Done"; die(); } ?> <fo
<?
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
echo "Operation Done";
die();
}
?>
<form action='page.php' method='post' name="myForm">
<input type="text" maxlength="50" name="name" class="input400" />
<input type="submit" name="Submit" />
</form>
当表单被提交时,数据被插入数据库,并生成消息操作Done。然后,如果刷新页面,数据将再次插入数据库
如何避免这个问题?任何建议都将不胜感激:)不要在创建操作后显示响应;改为在操作完成后重定向到另一页。如果有人刷新,他们正在刷新您重定向到的“获取请求”页面
// submit
// set success flash message (you are using a framework, right?)
header('Location: /path/to/record');
exit;
当表单显示时,在会话中设置一个随机数,并将该数字放入隐藏字段。如果发布的编号与会话编号匹配,则删除会话,运行查询;如果没有,则重新显示表单,并生成新的会话号。这是XSRF令牌的基本概念,您可以在此处阅读更多关于它们的信息,以及它们在安全方面的用途: 以下是一个例子:
<?php
session_start();
if (isset($_POST['formid']) && isset($_SESSION['formid']) && $_POST["formid"] == $_SESSION["formid"])
{
$_SESSION["formid"] = '';
echo 'Process form';
}
else
{
$_SESSION["formid"] = md5(rand(0,10000000));
?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<input type="hidden" name="formid" value="<?php echo htmlspecialchars($_SESSION["formid"]); ?>" />
<input type="submit" name="submit" />
</form>
<?php } ?>
像这样:
<?php
if(isset($_POST['uniqid']) AND $_POST['uniqid'] == $_SESSION['uniqid']){
// can't submit again
}
else{
// submit!
$_SESSION['uniqid'] = $_POST['uniqid'];
}
?>
<form action="page.php" method="post" name="myForm">
<input type="hidden" name="uniqid" value="<?php echo uniqid();?>" />
<!-- the rest of the fields here -->
</form>
我觉得比较简单
page.php
<?php
session_start();
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
$_SESSION["message"]="Operation Done";
header("Location:page.php");
exit;
}
?>
<html>
<body>
<div style='some styles'>
<?php
//message here
echo $_SESSION["message"];
?>
</div>
<form action='page.php' method='post'>
<!--elements-->
</form>
</body>
</html>
所以,对于我所需要的,这就是有效的
基于上述所有解决方案,这使我能够从一个表单转到另一个表单,再转到n^表单,同时防止在刷新页面时重复“保存”相同的确切数据(并且以前的post数据会停留在新页面上)
感谢那些发布了他们的解决方案的人,这很快让我找到了自己的解决方案
<?php
//Check if there was a post
if ($_POST) {
//Assuming there was a post, was it identical as the last time?
if (isset($_SESSION['pastData']) AND $_SESSION['pastData'] != $_POST) {
//No, Save
} else {
//Yes, Don't save
}
} else {
//Save
}
//Set the session to the most current post.
$_session['pastData'] = $_POST;
?>
我们在web应用程序上设计了大量php表单。写另一个页面来获取数据并提交每个表单是很麻烦的。为了避免重新提交,我们在每个表中创建了一个标记为“唯一”的“随机检查”字段
在页面加载时生成一个随机值,并将其存储在文本字段中(显然是隐藏的)
提交时,将此随机文本值保存在表中的“随机检查”字段中。在重新提交的情况下,查询将出错,因为它无法插入重复的值
之后,您可以显示错误,如
if ( !$result ) {
die( '<script>alertify.alert("Error while saving data OR you are resubmitting the form.");</script>' );
}
if(!$result){
死亡('alertify.alert(“保存数据时出错或您正在重新提交表单。”);');
}
无需重定向
更换die()代码>带有
isset(! $_POST['name']);
,将isset设置为isset not等于$_POST['name'],因此当您刷新它时,它将不会再添加到您的数据库中,除非您再次单击“提交”按钮
<?
if (isset($_POST['name'])) {
... operation on database, like to insert $_POST['name'] in a table ...
echo "Operation Done";
isset(! $_POST['name']);
}
?>
<form action='page.php' method='post' name="myForm">
<input type="text" maxlength="50" name="name" class="input400" />
<input type="submit" name="Submit" />
</form>
发生这种情况是因为只要刷新,它就会再次提交您的请求
因此,解决这一问题的思路是治本
我的意思是我们可以在表单中设置一个会话变量,并在更新时检查它
if($_SESSION["csrf_token"] == $_POST['csrf_token'] )
{
// submit data
}
//inside from
$_SESSION["csrf_token"] = md5(rand(0,10000000)).time();
<input type="hidden" name="csrf_token" value="
htmlspecialchars($_SESSION["csrf_token"]);">
if($\u会话[“csrf\u令牌”]=$\u POST['csrf\u令牌])
{
//提交数据
}
//从内到外
$\会话[“csrf\ U令牌”]=md5(兰特(010000000)).time();
我遇到了类似的问题。我需要向用户显示帖子的结果。我不想使用会话,也不想在URL中重定向结果(这有点安全,我不想它意外地被书签)。我找到了一个非常简单的解决方案,应该适用于其他答案中提到的案例
成功提交表单后,在页面上包含以下Javascript:
history.pushState({},“,”)
它将当前URL推送到历史堆栈上。由于这是历史记录中的新项目,刷新将不会重新发布
更新:这在Safari中不起作用。这是一个已知的错误。但由于它最初是在2017年报告的,因此可能不会很快得到修复。我尝试了一些方法(replaceState等),但在Safari中还没有找到解决方法。以下是有关该问题的一些相关链接:
我认为以下是避免重新提交或刷新页面的更好方法
$sample = $_POST['submit'];
if ($sample == "true")
{
//do it your code here
$sample = "false";
}
这是你应该一直做的。这个模式甚至有一个wiki页面:这是一个很好的解决方案,并且通过使用一些框架(比如Struts2或JSF,我以前已经做过)很容易实现。事实上,我不知道php的最佳策略:)简单、明显、优雅等等=)不错的策略!当然,我必须用新页面作为重定向来实现所有表单(该死…)!谢谢:)P.S.是否可以在POST中传递头函数的一些变量?或者只有trought GET?所有的post数据都添加到会话中了吗?如果会话过期,则为传统:如果(!empty($\u session[“formid”])&&&$\u post[“formid”]==$\u session[“formid”]),谢谢Joefay,你说得对,在使用它之前,我一定要检查会话中是否仍然存在formid
。我已经更新了我的答案。我们遇到了一个奇怪的情况,$\u POST['form']
和$\u SESSION['form']
变成了一个空字符串。因此,isset(…)
返回true,条件已满。我们还必须测试!为空($\u会话[“formid”])
。用户仍将收到浏览器警告,对吗?有没有办法避免这种情况?我们想要吗?谢谢分享。请确保将来正确格式化您的答案,以帮助其他读者!这是一个完美的答案。我认为这应该是最好的答案。这看起来不适合我Safari@Mav2287抢手货我用一些关于Safari的注释更新了答案。如果您找到解决方法,请告诉我!