按f5时避免在php中重新提交表单

时间:2009-04-06 18:06:55

标签: php form-submit

我在我的网站上有以下代码(使用php和smarty)尝试避免在我点击f5时重新提交表单:

if ($this->bln_added == false) {
    if (isset($_POST['submit'])) {
        $this->obj_site->obj_smarty->assign('title', $_POST['tas_heading']);
        $this->obj_site->obj_smarty->assign('desc', $_POST['tas_description']);
    }
} else {
    $this->obj_site->obj_smarty->assign('title', '');
    $this->obj_site->obj_smarty->assign('desc', '');
    unset($_POST);
}

默认情况下,bln_added为false,但在成功提交表单后更改为true。模板中使用了smarty变量title和desc来保存表单内容,以防出现用户错误,并且需要更改输入的内容。

如果表单成功提交,则设置bln_added = true,因此第二位代码不仅要清除表单字段,还要清空$ _POST。但如果按f5,帖子数据仍然存在。

有什么想法吗?

11 个答案:

答案 0 :(得分:40)

你的方法可以在理论上运作,但有一种更简单的方法。

成功提交表单后,执行重定向。无所谓,但它会清除$ _POST。

header('Location: http://www.example.com/form.php');

在您的情况下,听起来您想要重定向到您已经在的页面。如果要显示确认消息,请在URL中附加$ _GET参数。

希望这有帮助,

汤姆

答案 1 :(得分:9)

解决方案是一种通常称为Post/Redirect/Get

的模式

答案 2 :(得分:6)

处理表单的最佳方法是使用自我提交和重定向。像这样:

if (isset($_POST)) {
  // Perform your validation and whatever it is you wanted to do
  // Perform your redirect
}

// If we get here they didn't submit the form - display it to them.

使用CodeIgniter framework

function index() {
  $this->load->library('validation');
  // Your validation rules

  if ($this->form_validation->run()) {
    // Perform your database changes via your model
    redirect('');
    return;
  }
  // The form didn't validate (or the user hasn't submitted)
  $this->load->view('yourview');
}

答案 3 :(得分:2)

您可以将表单提交重写为AJAX方式。如果您需要显示HTML内容,请以JSON格式返回并使用JavaScript(例如jQuery)插入。

答案 4 :(得分:1)

我解决了这个问题(在php中):

  1. 在表单中添加一个不基于时间的唯一标识符(id + counter)()(!!!)

  2. 发布到单独的文件(postform.php),该文件检查具有该唯一标识符的会话

  3. a)如果找不到具有唯一标识符的会话:发布到数据库并使用唯一标识符填充会话

    b)如果找到具有唯一标识符的会话:什么都不做

  4. 在3a / 3b重定向到带有标题的结果页面后,
  5. ('位置:http://mydomain.com/mypage')

  6. 结果是:
    刷新/后退按钮没有重新提交操作,只在双击后退按钮时重新提交警告(但没有重新提交操作)

答案 5 :(得分:1)

成功发布帖子后使用标题位置

header('Location: '.$_SERVER['HTTP_REFERER']);

答案 6 :(得分:1)

如果我在代码末尾使用header()或exit(),例如保存一些数据后,它对我有用。

答案 7 :(得分:1)

我发现最好的方法是使用javascript和css。常见的php重定向方法标题('Location:http://www.yourdomain.com/url);将工作,但它会导致警告“警告:不能修改标题信息 - 标题已经发送”在不同的框架和cms如wordpress,drupal等所以我的建议是遵循以下代码

echo '<style>body{display:none;}</style>'; 
echo '<script>window.location.href = "http://www.siteurl.com/mysuccesspage";</script>'; 
exit;

样式标记很重要,否则用户可能会觉得页面加载了两次。如果我们使用body标签和body display none然后刷新页面,那么用户体验将与php header相同('Location:....);

我希望这会有所帮助:)

答案 8 :(得分:1)

您正在寻找的答案就是这条神奇的衬垫: header('Location: '.$_SERVER['HTTP_REFERER']);

例如

if(isset['submit']){
    //insert database
    header('Location: '.$_SERVER['HTTP_REFERER']);
}

答案 9 :(得分:0)

发布后的标题重定向是必要的,但不够。

在成功提交表单后的PHP端,执行重定向。例如。标题('位置:http://www.example.com/form.php');

但这还不够。有些用户按两次链接(双击)。需要JavaScript才能在首次单击后禁用提交按钮。

答案 10 :(得分:0)

尝试我自己的一个,也许它不是最佳解决方案(快速完成),但我已经测试过它并且有效。在Chrome上测试过。 Click to see how it looks BR

 <?php 
session_start(); // Start session
?>
<html>
 <head>
  <title>
    Test
  </title>
 </head>
 <body>
   <form name="test" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
   <input type="text" name="name"><br>
   <input type="submit" name="submit" value="Submit Form"><br>
  </form>

  <?php

  if(isset($_POST['submit']))
    {
     $_SESSION['name'] = $_POST['name']; //  Assign $_POST value to $_SESSION variable
      header('Location: refresh.php'); // Address of this - reloaded page - in this case similar to PHP_SELF
    } else session_destroy(); // kill session, depends on what you want to do / maybe unset() function will be enough

  if(isset($_SESSION['name']))
    {
     $name = $_SESSION['name'];

     echo "User Has submitted the form and entered this name : <b> $name </b>";
     echo "<br>You can use the following form again to enter a new name."; 
    }
  ?>
 </body>
</html>