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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/722547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 23:39:04  来源:igfitidea点击:

Avoiding form resubmit in php when pressing f5

phpform-submit

提问by wheresrhys

I have the following code on my site (using php and smarty) to try and avoid a form resubmitting when I hit f5:

我的网站上有以下代码(使用 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 is false by default, but changes to true once the form is successfully submitted. The smarty variables title and desc are used in the template to keep the form content there in case there is a user error and they need to change what they entered.

bln_ added 默认为 false,但一旦表单成功提交后更改为 true。模板中使用了智能变量 title 和 desc 以将表单内容保留在那里,以防出现用户错误并且他们需要更改输入的内容。

If the form is submitted successfully it sets bln_added = true, so the second bit of code should not only clear the form fields, but also empty $_POST. But if I press f5 the post data is still there.

如果表单提交成功,它会设置bln_ added = true,所以第二位代码不仅应该清除表单字段,还应该清空$_POST。但是如果我按 f5 后数据仍然存在。

Any ideas?

有任何想法吗?

回答by Tom Wright

Your method could work in theory, but there's a much easier way.

您的方法理论上可行,但还有更简单的方法。

After submitting the form successfully, perform a redirect. It doesn't matter where to, but it'll clear the $_POST.

成功提交表单后,执行重定向。去哪里无关紧要,但它会清除 $_POST。

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

In your case, it sounds like you want to redirect to the page you're already on. Append a $_GET parameter to the URL if you want to display a confirmation message.

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

Hope this helps,

希望这可以帮助,

Tom

汤姆

回答by David Snabel-Caunt

The solution is a pattern commonly known as Post/Redirect/Get

解决方案是通常称为Post/Redirect/Get 的模式

回答by Michael Wales

The best way to handle forms is to use self-submission and a redirect. Something like this:

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

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.

Using the CodeIgniter framework:

使用CodeIgniter 框架

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');
}

回答by ShiftedReality

You can rewrite your form-submit into AJAX-way. If you need to show HTML-content, return it in JSON-format and insert with JavaScript(jQuery for example.)

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

回答by Misterk

It works for me if I use either header() or exit() at the end of my code, for example, after I save some data.

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

回答by Ajith

The best method I found is using javascript and css. Common php redirection method header('Location: http://www.yourdomain.com/url); will work but It cause warning " Warning: Cannot modify header information - headers already sent" in different frameworks and cms like wordpress, drupal etc. So my suggestion is to follow the below code

我发现最好的方法是使用 javascript 和 css。常见的php重定向方法header('位置: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;

The style tag is important otherwise the user may feel like page loaded twice. If we use style tag with body display none and then refresh the page , then the user experience will be like same as php header('Location: ....);

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

I hope this will help :)

我希望这个能帮上忙 :)

回答by Paul

I solved this (in php) by:

我通过以下方式解决了这个问题(在 php 中):

  1. in the form add a unique identifier (id+counter) not based on time() (!!!)

  2. post to a separate file (postform.php) that checked for a session with that unique identifier

  3. a) if session with unique identifier was NOT found: post to the database and fill session with unique identifier

    b) if session with unique identifier was found: do nothing

  4. after either 3a/3b redirect to result page with header('Location: http://mydomain.com/mypage')

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

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

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

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

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

Result is:
no resubmit actions on either refresh/backbutton and only resubmit warning on double click backbutton (but no resubmit action)

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

回答by Mehmet Ali Uysal

Use Header location after successful post action

成功发布操作后使用标题位置

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

回答by Adrian Rybka

Try my own one, maybe it isn't best solution (done quickly), but I've test it and it works. Tested on Chrome. Click to see how it looksBR

试试我自己的,也许这不是最好的解决方案(很快完成),但我已经测试过它并且它有效。在 Chrome 上测试。单击以查看它的外观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>

回答by Mangirdas Skripka

Header redirect after post is necessary, but insufficient.

帖子后的标题重定向是必要的,但还不够。

In PHP side after submitting the form successfully, perform a redirect. Eg. header('Location: http://www.example.com/form.php');

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

But it is not enough. Some users press links twice (doubleclick). A JavaScript is required that would disable submit button after first click.

但这还不够。一些用户按链接两次(双击)。需要一个 JavaScript 来在第一次点击后禁用提交按钮。