如何防止刷新页面时重新提交表单(F5 / CTRL+R)

发布于 2024-11-15 04:30:43 字数 179 浏览 5 评论 0原文

我有一个简单的表单,可以将文本提交到我的 SQL 表。问题是,用户提交文本后,他们可以刷新页面并再次提交数据,而无需再次填写表单。我可以在提交文本后将用户重定向到另一个页面,但我希望用户留在同一页面上。

我记得读过一些关于为每个用户提供唯一的会话 ID 并将其与另一个值进行比较的内容,这解决了我遇到的问题,但我忘记了它在哪里。

I have a simple form that submits text to my SQL table. The problem is that after the user submits the text, they can refresh the page and the data gets submitted again without filling the form again. I could redirect the user to another page after the text is submitted, but I want users to stay on the same page.

I remember reading something about giving each user a unique session id and comparing it with another value which solved the problem I am having but I forgot where it is.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

岁月染过的梦 2024-11-22 04:30:43

我还想指出,您可以使用 JavaScript 方法 window.history.replaceState 来防止刷新和后退按钮时重新提交。

<script>
    if ( window.history.replaceState ) {
        window.history.replaceState( null, null, window.location.href );
    }
</script>

我仍然推荐 Post/Redirect/Get 方法,但这是一种新颖的 JS 解决方案。

I would also like to point out that you can use a javascript approach, window.history.replaceState to prevent a resubmit on refresh and back button.

<script>
    if ( window.history.replaceState ) {
        window.history.replaceState( null, null, window.location.href );
    }
</script>

I would still recommend a Post/Redirect/Get approach, but this is a novel JS solution.

眼睛会笑 2024-11-22 04:30:43

使用发布/重定向/获取模式。 http://en.wikipedia.org/wiki/Post/Redirect/Get

在我的网站中,我将在 cookie 或会话中存储消息,在发布后重定向,读取 cookie/会话,然后清除该会话或 cookie 变量的值。

Use the Post/Redirect/Get pattern. http://en.wikipedia.org/wiki/Post/Redirect/Get

With my website, I will store a message in a cookie or session, redirect after the post, read the cookie/session, and then clear the value of that session or cookie variable.

別甾虛僞 2024-11-22 04:30:43

您可以通过会话变量防止表单重新提交。

首先,您必须在文本框中设置 rand() 并在表单页面上设置 $_SESSION['rand']

<form action="" method="post">
  <?php
   $rand=rand();
   $_SESSION['rand']=$rand;
  ?>
 <input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
   Your Form's Other Field 
 <input type="submit" name="submitbtn" value="submit" />
</form>

之后检查 $_SESSION['rand' ] 与文本框 $_POST['randcheck']
像这样:

if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
{
    // Your code here
}

确保在使用 session_start() 使用的每个文件上启动会话

You can prevent form resubmission via a session variable.

First you have to set rand() in a textbox and $_SESSION['rand'] on the form page:

<form action="" method="post">
  <?php
   $rand=rand();
   $_SESSION['rand']=$rand;
  ?>
 <input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
   Your Form's Other Field 
 <input type="submit" name="submitbtn" value="submit" />
</form>

After that check $_SESSION['rand'] with textbox $_POST['randcheck'] value
like this:

if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
{
    // Your code here
}

Make sure you start the session on every file you are using it with session_start()

老子叫无熙 2024-11-22 04:30:43

我使用此 JavaScript 行来阻止在提交表单后刷新时要求重新提交表单的弹出窗口。

if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}

只需将此行放在文件的页脚即可看到神奇的效果

I use this javascript line to block the pop up asking for form resubmission on refresh once the form is submitted.

if ( window.history.replaceState ) {
  window.history.replaceState( null, null, window.location.href );
}

Just place this line at the footer of your file and see the magic

梦里泪两行 2024-11-22 04:30:43

您确实应该使用 Post Redirect Get 模式来处理此问题,但如果您以某种方式最终处于 PRG 不可行的位置(例如,表单本身位于包含中,防止重定向),您可以散列一些请求参数根据内容创建一个字符串,然后检查您是否尚未发送。

//create digest of the form submission:

    $messageIdent = md5($_POST['name'] . $_POST['email'] . $_POST['phone'] . $_POST['comment']);

//and check it against the stored value:

    $sessionMessageIdent = isset($_SESSION['messageIdent'])?$_SESSION['messageIdent']:'';

    if($messageIdent!=$sessionMessageIdent){//if its different:          
        //save the session var:
            $_SESSION['messageIdent'] = $messageIdent;
        //and...
            do_your_thang();
    } else {
        //you've sent this already!
    }

You should really use a Post Redirect Get pattern for handling this but if you've somehow ended up in a position where PRG isn't viable (e.g. the form itself is in an include, preventing redirects) you can hash some of the request parameters to make a string based on the content and then check that you haven't sent it already.

//create digest of the form submission:

    $messageIdent = md5($_POST['name'] . $_POST['email'] . $_POST['phone'] . $_POST['comment']);

//and check it against the stored value:

    $sessionMessageIdent = isset($_SESSION['messageIdent'])?$_SESSION['messageIdent']:'';

    if($messageIdent!=$sessionMessageIdent){//if its different:          
        //save the session var:
            $_SESSION['messageIdent'] = $messageIdent;
        //and...
            do_your_thang();
    } else {
        //you've sent this already!
    }
人心善变 2024-11-22 04:30:43

处理表单后,您将重定向到另一个页面:

... process complete....
header('Location: thankyou.php');

您也可以重定向到同一页面。

如果您正在执行评论之类的操作并且希望用户停留在同一页面上,则可以使用 Ajax 来处理表单提交

When the form is processed, you redirect to another page:

... process complete....
header('Location: thankyou.php');

you can also redirect to the same page.

if you are doing something like comments and you want the user to stay on the same page, you can use Ajax to handle the form submission

娇女薄笑 2024-11-22 04:30:43

我找到了下一个解决方法。您可以在处理 POST 请求后通过操作 history 来逃避重定向目的。

所以你有 HTML 表单:

<form method=POST action='/process.php'>
 <input type=submit value=OK>
</form>

当你在服务器上处理此表单时,你不是通过设置 Location 标头将用户重定向到 /the/result/page,如下所示:

$cat process.php
<?php 
     process POST data here
     ... 
     header('Location: /the/result/page');
     exit();
?>

输入图像描述这里

处理后POST 渲染的数据很小

<?php 
     process POST data here
     render the <script>         // see below
     render `/the/result/page`   // OK
?>

<script>
    window.onload = function() {
        history.replaceState("", "", "/the/result/page");
    }
</script>

结果是:

在此处输入图像描述

您可以看到表单数据被 POST 编辑到 process.php 脚本。
此脚本处理POST数据并立即渲染/the/result/page

  1. 无重定向
  2. ,无重新POST > 刷新页面 (F5) 时的数据
  3. 当您通过浏览器历史记录导航到上一页/下一页时,不会重新POST

UPD

作为另一个解决方案,我问 功能请求Mozilla FireFox团队允许用户设置< code>NextPage 标头,其工作方式类似于 Location 标头,并使 post/redirect/get 模式过时。

简而言之。当服务器成功处理表单 POST 数据时:

  1. 设置 NextPage 标头而不是 Location
  2. 渲染处理 POST 表单的结果以 post/redirect/get 模式呈现 GET 请求的数据

浏览器在看到 NextPage 标头时依次:

  1. 调整 window.locationNextPage
  2. 当用户刷新页面时,浏览器将协商 GET 请求到 NextPage,而不是重新POST 表单数据

我认为如果实现的话,这将是非常好的,不是? <代码>=)

I found next workaround. You may escape the redirection after processing POST request by manipulating history object.

So you have the HTML form:

<form method=POST action='/process.php'>
 <input type=submit value=OK>
</form>

When you process this form on your server you instead of redirecting user to /the/result/page by setting up the Location header like this:

$cat process.php
<?php 
     process POST data here
     ... 
     header('Location: /the/result/page');
     exit();
?>

enter image description here

After processing POSTed data you render small <script> and the result /the/result/page

<?php 
     process POST data here
     render the <script>         // see below
     render `/the/result/page`   // OK
?>

The <script> you should render:

<script>
    window.onload = function() {
        history.replaceState("", "", "/the/result/page");
    }
</script>

The result is:

enter image description here

as you can see the form data is POSTed to process.php script.
This script process POSTed data and rendering /the/result/page at once with:

  1. no redirection
  2. no rePOST data when you refresh page (F5)
  3. no rePOST when you navigate to previous/next page through the browser history

UPD

As another solution I ask feature request the Mozilla FireFox team to allow users to setup NextPage header which will work like Location header and make post/redirect/get pattern obsolete.

In short. When server process form POST data successfully it:

  1. Setup NextPage header instead of Location
  2. Render the result of processing POST form data as it would render for GET request in post/redirect/get pattern

The browser in turn when see the NextPage header:

  1. Adjust window.location with NextPage value
  2. When user refresh the page the browser will negotiate GET request to NextPage instead of rePOST form data

I think this would be excelent if implemented, would not? =)

花想c 2024-11-22 04:30:43
  1. 使用标头并重定向页面。

    header("Location:your_page.php"); 您可以重定向到同一页面或不同页面。

  2. 将$_POST插入数据库后取消设置。

    unset($_POST);

  1. Use header and redirect the page.

    header("Location:your_page.php"); You can redirect to same page or different page.

  2. Unset $_POST after inserting it to Database.

    unset($_POST);

一花一树开 2024-11-22 04:30:43

一个非常可靠的方法是在帖子中实现一个唯一的 ID 并将其缓存在

<input type='hidden' name='post_id' value='".createPassword(64)."'>

然后在代码中执行以下操作:

if( ($_SESSION['post_id'] != $_POST['post_id']) )
{
    $_SESSION['post_id'] = $_POST['post_id'];
    //do post stuff
} else {
    //normal display
}

function createPassword($length)
{
    $chars = "abcdefghijkmnopqrstuvwxyz023456789";
    srand((double)microtime()*1000000);
    $i = 0;
    $pass = '' ;

    while ($i <= ($length - 1)) {
        $num = rand() % 33;
        $tmp = substr($chars, $num, 1);
        $pass = $pass . $tmp;
        $i++;
    }
    return $pass;
}

A pretty surefire way is to implement a unique ID into the post and cache it in the

<input type='hidden' name='post_id' value='".createPassword(64)."'>

Then in your code do this:

if( ($_SESSION['post_id'] != $_POST['post_id']) )
{
    $_SESSION['post_id'] = $_POST['post_id'];
    //do post stuff
} else {
    //normal display
}

function createPassword($length)
{
    $chars = "abcdefghijkmnopqrstuvwxyz023456789";
    srand((double)microtime()*1000000);
    $i = 0;
    $pass = '' ;

    while ($i <= ($length - 1)) {
        $num = rand() % 33;
        $tmp = substr($chars, $num, 1);
        $pass = $pass . $tmp;
        $i++;
    }
    return $pass;
}
一页 2024-11-22 04:30:43

Moob 帖子的精炼版。创建 POST 的哈希值,将其保存为会话 cookie,并比较每个会话的哈希值。

// Optionally Disable browser caching on "Back"
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Expires: Sun, 1 Jan 2000 12:00:00 GMT' );
header( 'Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT' );

$post_hash = md5( json_encode( $_POST ) );

if( session_start() )
{
    $post_resubmitted = isset( $_SESSION[ 'post_hash' ] ) && $_SESSION[ 'post_hash' ] == $post_hash;
    $_SESSION[ 'post_hash' ] = $post_hash;
    session_write_close();
}
else
{
    $post_resubmitted = false;
}

if ( $post_resubmitted ) {
  // POST was resubmitted
}
else
{
  // POST was submitted normally
}

A refined version of Moob's post. Create a hash of the POST, save it as a session cookie, and compare hashes every session.

// Optionally Disable browser caching on "Back"
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Expires: Sun, 1 Jan 2000 12:00:00 GMT' );
header( 'Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT' );

$post_hash = md5( json_encode( $_POST ) );

if( session_start() )
{
    $post_resubmitted = isset( $_SESSION[ 'post_hash' ] ) && $_SESSION[ 'post_hash' ] == $post_hash;
    $_SESSION[ 'post_hash' ] = $post_hash;
    session_write_close();
}
else
{
    $post_resubmitted = false;
}

if ( $post_resubmitted ) {
  // POST was resubmitted
}
else
{
  // POST was submitted normally
}
怪我闹别瞎闹 2024-11-22 04:30:43

基本上,您需要重定向出该页面,但当您的互联网速度较慢时,它仍然会出现问题(从服务器端重定向标头)

基本场景示例:

单击提交按钮两次

解决

  • 客户端

    的 方法

    • 一旦客户点击提交按钮,就会禁用该按钮
    • 如果您使用 Jquery :Jquery.one
    • PRG 模式
  • 服务器端

    • 使用基于差异的哈希时间戳/发送请求时的时间戳。
    • 用户请求令牌。当主加载时分配一个临时请求令牌,如果重复则忽略该令牌。

Basically, you need to redirect out of that page but it still can make a problem while your internet slow (Redirect header from serverside)

Example of basic scenario :

Click on submit button twice

Way to solve

  • Client side

  • Server side

    • Using differentiate based hashing timestamp / timestamp when request was sent.
    • Userequest tokens. When the main loads up assign a temporary request tocken which if repeated is ignored.
戴着白色围巾的女孩 2024-11-22 04:30:43

如何防止 php 表单重新提交而不重定向。如果您使用 $_SESSION (在 session_start 之后)和 $_POST 表单,您可以执行以下操作:

if ( !empty($_SESSION['act']) && !empty($_POST['act']) && $_POST['act'] == $_SESSION['act'] ) {
  // do your stuff, save data into database, etc
}

在您的 html 表单中输入以下内容:

<input type="hidden" id="act" name="act" value="<?php echo ( empty($_POST['act']) || $_POST['act']==2 )? 1 : 2; ?>">
<?php
if ( $_POST['act'] == $_SESSION['act'] ){
    if ( empty( $_SESSION['act'] ) || $_SESSION['act'] == 2 ){
        $_SESSION['act'] = 1;
    } else {
        $_SESSION['act'] = 2;
    }
}
?>

因此,每次提交表单时,都会生成一个新的行为,存储在会话中并与事后行为相比。

Ps:如果您使用的是 Get 表单,您可以轻松地将所有 POST 更改为 GET,并且它也可以工作。

How to prevent php form resubmission without redirect. If you are using $_SESSION (after session_start) and a $_POST form, you can do something like this:

if ( !empty($_SESSION['act']) && !empty($_POST['act']) && $_POST['act'] == $_SESSION['act'] ) {
  // do your stuff, save data into database, etc
}

In your html form put this:

<input type="hidden" id="act" name="act" value="<?php echo ( empty($_POST['act']) || $_POST['act']==2 )? 1 : 2; ?>">
<?php
if ( $_POST['act'] == $_SESSION['act'] ){
    if ( empty( $_SESSION['act'] ) || $_SESSION['act'] == 2 ){
        $_SESSION['act'] = 1;
    } else {
        $_SESSION['act'] = 2;
    }
}
?>

So, every time when the form is submitted, a new act is generated, stored in session and compared with the post act.

Ps: if you are using an Get form, you can easily change all POST with GET and it works too.

叹倦 2024-11-22 04:30:43

$_POST['submit'] 变量在页面初始加载时不存在,并且仅当以下条件为真时才能运行curl。

if($_POST['submit'] == "submit"){

// This is where you run the Curl code and display the output
  $curl = curl_init();



//clear $post variables after posting
$_POST = array();

}

The $_POST['submit'] variable would not exist on initial loading of page, and curl can be run only if below condition is true.

if($_POST['submit'] == "submit"){

// This is where you run the Curl code and display the output
  $curl = curl_init();



//clear $post variables after posting
$_POST = array();

}
屌丝范 2024-11-22 04:30:43

插入数据库后,调用unset()方法清除数据。

unset($_POST);

要防止刷新数据插入,请在记录插入后执行页面重定向到同一页面或不同页面。

header('位置:'.$_SERVER['PHP_SELF']);

After inserting it to database, call unset() method to clear the data.

unset($_POST);

To prevent refresh data insertion, do a page redirection to same page or different page after record insert.

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

风吹雪碎 2024-11-22 04:30:43

使用 Keverw 答案中的 Post/Redirect/Get 模式是一个好主意。但是,您无法停留在您的页面上(我认为这就是您所要求的?)此外,有时可能失败

如果网络用户在初始提交完成之前刷新
由于服务器延迟,导致重复的 HTTP POST 请求
某些用户代理。

如果应将文本写入 SQL 数据库,另一种选择是存储在会话中,如下所示:

if($_SERVER['REQUEST_METHOD'] != 'POST')
{
  $_SESSION['writeSQL'] = true;
}
else
{
  if(isset($_SESSION['writeSQL']) && $_SESSION['writeSQL'])
  {
    $_SESSION['writeSQL'] = false;

    /* save $_POST values into SQL */
  }
}

Using the Post/Redirect/Get pattern from Keverw answer is a good idea. However, you are not able to stay on your page (and I think this was what you were asking for?) In addition, it may sometimes fail:

If a web user refreshes before the initial submission has completed
because of server lag, resulting in a duplicate HTTP POST request in
certain user agents.

Another option would be to store in a session if text should be written to your SQL database like this:

if($_SERVER['REQUEST_METHOD'] != 'POST')
{
  $_SESSION['writeSQL'] = true;
}
else
{
  if(isset($_SESSION['writeSQL']) && $_SESSION['writeSQL'])
  {
    $_SESSION['writeSQL'] = false;

    /* save $_POST values into SQL */
  }
}
悲喜皆因你 2024-11-22 04:30:43

正如其他人所说,不可能不使用 post/redirect/get。但同时在服务器端做你想做的事情也很容易。

在 POST 页面中,您只需验证用户输入,但不对其进行操作,而是将其复制到 SESSION 数组中。然后您再次重定向回主提交页面。您的主提交页面首先检查您正在使用的 SESSION 数组是否存在,如果存在,则将其复制到本地数组中并取消设置。从那里您可以采取行动。

这样你只需完成所有主要工作一次,即可实现你想做的事情。

As others have said, it is not possible to out of using post/redirect/get. But at the same time it is quite easy to do what you want to do server side.

In your POST page you simply validate the user input but do not act on it, instead you copy it into a SESSION array. You then redirect back to the main submission page again. Your main submission page starts by checking to see if the SESSION array that you are using exists, and if so copy it into a local array and unset it. From there you can act on it.

This way you only do all your main work once, achieving what you want to do.

萌面超妹 2024-11-22 04:30:43

我后来寻找解决方案来防止在一个巨大的项目中重新提交。
该代码与 $_GET 和 $_POST 高度兼容,并且我无法在没有不可预见错误风险的情况下更改表单元素行为。
所以,这是我的代码:

<!-- language: lang-php -->
<?php

// Very top of your code:

// Start session:
session_start();

// If Post Form Data send and no File Upload
if ( empty( $_FILES ) && ! empty( $_POST ) ) {
    // Store Post Form Data in Session Variable
    $_SESSION["POST"] = $_POST;
    // Reload Page if there were no outputs
    if ( ! headers_sent() ) {
        // Build URL to reload with GET Parameters
        // Change https to http if your site has no ssl
        $location = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        // Reload Page
        header( "location: " . $location, true, 303 );
        // Stop any further progress
        die();
    }
}

// Rebuilt POST Form Data from Session Variable
if ( isset( $_SESSION["POST"] ) ) {
    $_POST = $_SESSION["POST"];
    // Tell PHP that POST is sent
    $_SERVER['REQUEST_METHOD'] = 'POST';
}

// Your code:
?><html>
    <head>
        <title>GET/POST Resubmit</title>
    </head>
    <body>

    <h1>Forms:</h1>
    <h2>GET Form:</h2>
    <form action="index.php" method="get">
        <input type="text" id="text_get" value="test text get" name="text_get"/>
        <input type="submit" value="submit">
    </form>
    <h2>POST Form:</h2>
    <form action="index.php" method="post">
        <input type="text" id="text_post" value="test text post" name="text_post"/>
        <input type="submit" value="submit">
    </form>
    <h2>POST Form with GET action:</h2>
    <form action="index.php?text_get2=getwithpost" method="post">
        <input type="text" id="text_post2" value="test text get post" name="text_post2"/>
        <input type="submit" value="submit">
    </form>
    <h2>File Upload Form:</h2>
    <form action="index.php" method="post" enctype="multipart/form-data">
        <input type="file" id="file" name="file">
        <input type="submit" value="submit">
    </form>

    <h1>Results:</h1>
    <h2>GET Form Result:</h2>
    <p>text_get: <?php echo $_GET["text_get"]; ?></p>
    <h2>POST Form Result:</h2>
    <p>text_post: <?php echo $_POST["text_post"]; ?></p>
    <h2>POST Form with GET Result:</h2>
    <p>text_get2: <?php echo $_GET["text_get2"]; ?></p>
    <p>text_post2: <?php echo $_POST["text_post2"]; ?></p>
    <h2>File Upload:</h2>
    <p>file:
    <pre><?php if ( ! empty( $_FILES ) ) {
            echo print_r( $_FILES, true );
        } ?></pre>
    </p>
    <p></p>
    </body>
    </html><?php
// Very Bottom of your code:
// Kill Post Form Data Session Variable, so User can reload the Page without sending post data twice
unset( $_SESSION["POST"] );

它只能避免重新提交 $_POST,而不是 $_GET。但这是我需要的行为。
重新提交问题不适用于文件上传!

I searched for solution to prevent resubmission in a huge project afterwards.
The code highly works with $_GET and $_POST and I can't change the form elements behaviour without the risk of unforeseen bugs.
So, here is my code:

<!-- language: lang-php -->
<?php

// Very top of your code:

// Start session:
session_start();

// If Post Form Data send and no File Upload
if ( empty( $_FILES ) && ! empty( $_POST ) ) {
    // Store Post Form Data in Session Variable
    $_SESSION["POST"] = $_POST;
    // Reload Page if there were no outputs
    if ( ! headers_sent() ) {
        // Build URL to reload with GET Parameters
        // Change https to http if your site has no ssl
        $location = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        // Reload Page
        header( "location: " . $location, true, 303 );
        // Stop any further progress
        die();
    }
}

// Rebuilt POST Form Data from Session Variable
if ( isset( $_SESSION["POST"] ) ) {
    $_POST = $_SESSION["POST"];
    // Tell PHP that POST is sent
    $_SERVER['REQUEST_METHOD'] = 'POST';
}

// Your code:
?><html>
    <head>
        <title>GET/POST Resubmit</title>
    </head>
    <body>

    <h1>Forms:</h1>
    <h2>GET Form:</h2>
    <form action="index.php" method="get">
        <input type="text" id="text_get" value="test text get" name="text_get"/>
        <input type="submit" value="submit">
    </form>
    <h2>POST Form:</h2>
    <form action="index.php" method="post">
        <input type="text" id="text_post" value="test text post" name="text_post"/>
        <input type="submit" value="submit">
    </form>
    <h2>POST Form with GET action:</h2>
    <form action="index.php?text_get2=getwithpost" method="post">
        <input type="text" id="text_post2" value="test text get post" name="text_post2"/>
        <input type="submit" value="submit">
    </form>
    <h2>File Upload Form:</h2>
    <form action="index.php" method="post" enctype="multipart/form-data">
        <input type="file" id="file" name="file">
        <input type="submit" value="submit">
    </form>

    <h1>Results:</h1>
    <h2>GET Form Result:</h2>
    <p>text_get: <?php echo $_GET["text_get"]; ?></p>
    <h2>POST Form Result:</h2>
    <p>text_post: <?php echo $_POST["text_post"]; ?></p>
    <h2>POST Form with GET Result:</h2>
    <p>text_get2: <?php echo $_GET["text_get2"]; ?></p>
    <p>text_post2: <?php echo $_POST["text_post2"]; ?></p>
    <h2>File Upload:</h2>
    <p>file:
    <pre><?php if ( ! empty( $_FILES ) ) {
            echo print_r( $_FILES, true );
        } ?></pre>
    </p>
    <p></p>
    </body>
    </html><?php
// Very Bottom of your code:
// Kill Post Form Data Session Variable, so User can reload the Page without sending post data twice
unset( $_SESSION["POST"] );

It only works to avoid the resubmit of $_POST, not $_GET. But this is the behaviour I need.
The resubmit issue doesn't work with file uploads!

傾城如夢未必闌珊 2024-11-22 04:30:43

对我有用的是:

if ( !refreshed()) {
   //Your Submit Here
        if (isset( $_GET['refresh'])) {
            setcookie("refresh",$_GET['refresh'], time() + (86400 * 5), "/");
        }

    }    
}


function refreshed()
{
    if (isset($_GET['refresh'])) {
        $token = $_GET['refresh'];
        if (isset($_COOKIE['refresh'])) {
            if ($_COOKIE['refresh'] != $token) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}  


function createToken($length) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

?>

以你的形式

 <form  action="?refresh=<?php echo createToken(3)?>">



 </form>

What Works For Me is :

if ( !refreshed()) {
   //Your Submit Here
        if (isset( $_GET['refresh'])) {
            setcookie("refresh",$_GET['refresh'], time() + (86400 * 5), "/");
        }

    }    
}


function refreshed()
{
    if (isset($_GET['refresh'])) {
        $token = $_GET['refresh'];
        if (isset($_COOKIE['refresh'])) {
            if ($_COOKIE['refresh'] != $token) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
}  


function createToken($length) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

?>

And in your Form

 <form  action="?refresh=<?php echo createToken(3)?>">



 </form>
峩卟喜欢 2024-11-22 04:30:43
if (($_SERVER['REQUEST_METHOD'] == 'POST') and (isset($_SESSION['uniq']))){
    if($everything_fine){
        unset($_SESSION['uniq']);
    }
}
else{
    $_SESSION['uniq'] = uniqid();
}

$everything_fine 是表单验证的布尔结果。如果表单未验证,则通常会再次显示并提示要更正的内容,以便用户可以再次发送。因此,如果需要更正的形式,也会再次创建 $_SESSION['uniq']

if (($_SERVER['REQUEST_METHOD'] == 'POST') and (isset($_SESSION['uniq']))){
    if($everything_fine){
        unset($_SESSION['uniq']);
    }
}
else{
    $_SESSION['uniq'] = uniqid();
}

$everything_fine is the boolean result of form-validation. If the form is not validating then it shall be usually displayed again with a hint what to correct, so that the user can send it again. Therefore the $_SESSION['uniq'] is created again too if a corrected form is desired

花间憩 2024-11-22 04:30:43

这个 form.php 示例展示了如何正确使用 PRG(当表单有效或无效时)。

  • 仅当表单有效并且执行了操作时,它才会重定向到同一页面。
  • 重定向可防止表单在页面刷新时重新提交。
  • 如果表单有效,它使用会话不会丢失您想要显示的成功消息。
  • 有两个测试按钮:“有效提交”、“无效提交”。两者都尝试一下,然后刷新页面。
<?php
session_start();

function doSelfRedirect()
{
  header('Location:'.$_SERVER['PHP_SELF']);
  exit;
}

function setFlashMessage($msg)
{
  $_SESSION['message'] = $msg;
}

function getFlashMessage()
{
  if (!empty($_SESSION['message'])) {
    $msg = $_SESSION['message'];
    unset($_SESSION['message']);
  } else {
    $msg = null;
  }

  return $msg;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  // Validation primitive example.
  if (empty($_POST['valid'])) {
    $formIsValid = false;
    setFlashMessage('Invalid form submit');
  } else {
    $formIsValid = true;
  }

  if ($formIsValid) {
    // Perform any actions here.
    // ...

    // Cool!
    setFlashMessage('Form is valid. Action performed.');

    // Prevent form resubmission.
    doSelfRedirect();
  }
}
?>
<h1>Hello form</h1>

<?php if ($msg = getFlashMessage()): ?>
  <div><?= $msg ?></div>
<?php endif; ?>

<form method="post">
  <input type="text" name="foo" value="bar"><br><br>
  <button type="submit" name="invalid" value="0">Invalid submit</button>
  <button type="submit" name="valid" value="1">Valid submit</button>
</form>

This form.php sample shows how to use PRG correct (when form is valid or not).

  • It redirects to the same page only if form is valid and action was performed.
  • Redirection protects form from being resubmitted on page refresh.
  • It uses session to not lose success messages you want to show if form is valid.
  • There are two buttons for testing: "Valid submit", "Invalid submit". Try both and refresh page after that.
<?php
session_start();

function doSelfRedirect()
{
  header('Location:'.$_SERVER['PHP_SELF']);
  exit;
}

function setFlashMessage($msg)
{
  $_SESSION['message'] = $msg;
}

function getFlashMessage()
{
  if (!empty($_SESSION['message'])) {
    $msg = $_SESSION['message'];
    unset($_SESSION['message']);
  } else {
    $msg = null;
  }

  return $msg;
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  // Validation primitive example.
  if (empty($_POST['valid'])) {
    $formIsValid = false;
    setFlashMessage('Invalid form submit');
  } else {
    $formIsValid = true;
  }

  if ($formIsValid) {
    // Perform any actions here.
    // ...

    // Cool!
    setFlashMessage('Form is valid. Action performed.');

    // Prevent form resubmission.
    doSelfRedirect();
  }
}
?>
<h1>Hello form</h1>

<?php if ($msg = getFlashMessage()): ?>
  <div><?= $msg ?></div>
<?php endif; ?>

<form method="post">
  <input type="text" name="foo" value="bar"><br><br>
  <button type="submit" name="invalid" value="0">Invalid submit</button>
  <button type="submit" name="valid" value="1">Valid submit</button>
</form>
悲喜皆因你 2024-11-22 04:30:43

为什么不直接使用 $_POST['submit'] 变量作为逻辑语句来保存表单中的任何内容。您始终可以重定向到同一页面(如果它们刷新,并且当它们在浏览器中点击返回时,则不会再设置提交帖子变量。只需确保您的提交按钮有submitnameid

Why not just use the $_POST['submit'] variable as a logical statement in order to save whatever is in the form. You can always redirect to the same page (In case they refresh, and when they hit go back in the browser, the submit post variable wouldn't be set anymore. Just make sure your submit button has a name and id of submit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文