Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 避免由于页面刷新而提交的最佳方法_Php_Html_Forms - Fatal编程技术网

Php 避免由于页面刷新而提交的最佳方法

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

我认为这个问题经常发生在web应用程序开发中。但我会尽量详细解释我的问题

我想知道如何纠正这种行为,例如,当我有这样一块代码时:

<?
    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的注释更新了答案。如果您找到解决方法,请告诉我!