点击“返回”按钮后防止表单重复提交

4

我有两个页面:

page1.php:
- 有一个文本框和一个“提交”按钮的表单。例如:<form name="frm_register" action="page1.php" method="post">

- php和mysql代码将文本框的值存储到数据库中。当值提交到数据库后,Javascript会重定向到php2.php。例如:

$query = "INSERT INTO traceuser (username) VALUES ('{$username}')";
$result = mysql_query($query, $connection);
echo '<script language="javascript">window.location="page2.php";</script>';

page2.php
- 从数据库检索数据并在此页面上显示。

问题:当我按“返回”按钮时,浏览器会弹出一个警告消息,说表单将被重新提交。如何防止点击“返回”按钮时重新提交表单?我需要清除page1.php的缓存吗?如何使用php、javascript或ajax来实现?


更新1:感谢回答,用php header('Location: home2.php'); 替换 javascript window.location="page2.php",解决了80%的问题。剩下的20%问题如下:

    if (strtotime($_SESSION['servertime']) < time()-3){ //10800 = 3 hours 3600 = 1 hour
                if (($username != "") AND ($username != $_SESSION[username])){
                    $_SESSION['servertime'] = $servertime; 
                    $_SESSION['username'] = $username;
                    $query = "INSERT INTO traceuser (username) VALUES ('{$username}')";
                    $result = mysql_query($query20, $connection);
                    header('Location: page2.php');
                    exit;
                } else {
                    echo "same name"; //problem here
                }
            }else{
                echo "submit multiple data too fast"; //problem here too.
            }
   }

当执行以下步骤时出现问题:
1)用户成功提交数据,跳转到page2.php查看记录。
2)用户点击“返回”按钮,返回到page1.php。
3)用户提交数据失败,停留在page1.php。(因为太快或名称相同)
4)用户成功提交数据,跳转到page2.php查看记录。
5)用户单击“返回”按钮,但浏览器显示警告消息“表格将被重新提交”。
问题是由于第3步未运行header('Location: page2.php');,未跳转到page2.php。这导致第5步显示警告消息。如何解决这个问题?
更新2: 我已经找到了解决20%问题的方法,它完美地解决了问题。我使用session['error123']来决定是否想要显示错误消息“名称相同”。如果成功将数据提交到数据库或成功跳转到page2.php,则会清除session['error123']。我还使用header('Location: page1.php');重定向到自己的页面(同一页),以使页面忘记以前的表单提交。代码示例如下:
if ($_SESSION['error123'] == "toofast"){
    echo $_SESSION['error123'] ;
}elseif ($_SESSION['error123'] == "samename"){
    echo $_SESSION['error123'] ;
}

if (strtotime($_SESSION['servertime']) < time()-3){ //10800 = 3 hours 3600 = 1 hour
                if (($username != "") AND ($username != $_SESSION['username'])){
                    $_SESSION['username'] = $username;
                    $query = "INSERT INTO traceuser (username) VALUES ('{$username}')";
                    $result = mysql_query($query20, $connection);
                    $_SESSION['error123'] = "aa";
                    header('Location: http://localhost/plekz/page2.php');
                    exit;
                } else {
                    $_SESSION['error123'] = "samename";
                    header('Location: http://localhost/plekz/page1.php');
                    exit;
                }
            }else{
                $_SESSION['error123'] = "toofast";
                header('Location: http://localhost/plekz/page1.php');
                    exit;
            }
        }
    }

注意:您需要通过<?php ob_start();?>缓冲输出,因为在header()之前无法使用$_SESSION。缓冲将停止所有输出,包括会话,请让header()先发送输出。

你问题中剩下的20%与I am confused about PHP Post/Redirect/Get相同,同时可以参考这个tutorial,第二部分永远不要允许表单重新提交 - hakre
@hakre,您提出的解决方案是将提交表单数据的脚本与接收和处理该数据的脚本分开,对吗?如果我这样做,我的page1.php必须负责两个任务:1)如果$_Get['success']!=true,在页面上显示带有文本框和提交按钮的表单,并且如果$_Get['success']==true,则必须显示所有记录。如果显示记录取决于php if else语句,那么我需要用php echo包装显示记录的html代码。将所有html都包装在php echo中将是很多工作...天哪。 - zac1987
6个回答

4

与其使用

echo '<script language="javascript">window.location="page2.php";</script>';

你应该在提交后使用header()函数来重定向用户。

因此,在伪代码中,

在page.php上点击提交操作,页面page1.php将数据提交到数据库并调用

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

这应该可以解决您的网页返回问题


你好,你的解决方案解决了80%的问题,我更新了我的问题以展示剩下的20%问题,请教我如何解决它。谢谢。 - zac1987
@BenSwinburne:任何HTTP头部在冒号后都需要一个空格(SP)。位置头部需要绝对URI。请注意。 - hakre
@hakre 我的示例使用绝对URI...方案、主机名和绝对路径都在那里,以及一个单独的空格。你在评论中想表达什么? - Ben Swinburne
@BenSwinburne:只是想让你知道,我对你的答案进行了修正(改正了一些问题),这样你就可以知道了。就这样了 ;) - hakre
1
@zac1987:仅仅因为它在你的浏览器上运行正常,并不意味着它适用于每个浏览器。因为这并不是微不足道的,所以有一个标准,所有这些头部都被定义了,写下了如何使用这些头部的方法。通常称为RFC,例如,您正在使用HTTP 1/1位置:http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30。 - hakre
显示剩余2条评论

1

你好,你的解决方案解决了80%的问题,我已经更新了我的问题,展示了剩下的20%的问题,请教我如何解决。谢谢。 - zac1987
谢谢。我已经找到了两种不同的解决方案。感谢您的建议 :) - zac1987

0
你能用Ajax调用来完成吗?表单不需要进行任何操作,只需提交时调用Ajax函数。Ajax调用将执行查询并提供响应(您可以打印结果),然后您可以根据结果提供动态反馈。您永远不会离开页面。
<form id="thisForm">
...form input fields...
<input type="button" onclick="return submitForm('thisForm')"/>
</form>

function submitForm(formId) {
    $.ajax( {
        type: "post",
        url: 'page2.php',
        data: $('#' + formId + ' input').serialize(),
        ... any other Ajax parameters...,
        success: function(data) {
        }
    });
    return false;
}

顺便说一下,当进行Ajax调用时,您永远不会离开页面(例如,page1.php),因此返回按钮只会将您带回到之前的页面。页面刷新也不会再次执行Ajax调用。 - Keith DC
从您的代码中,您建议我不要离开page1.php页面,但我需要在page2.php上显示记录/数据,这意味着我需要离开page1.php并转到page2.php。这不是注册系统,请不要误解它。用户在page1.php提交数据后,必须重定向到page2.php。还有其他解决方案吗? - zac1987
我已经看到了onclick函数!! 如果刷新页面,该函数将不会再次调用,直到再次点击按钮。非常感谢!我认为你的答案将解决我的问题。我现在要进行测试。谢谢。 - zac1987
你可以将数据从页面2返回到Ajax调用(在页面2完成所需操作后),然后在仍在页面1上的情况下动态呈现数据。如果您返回了一张表格的数据,那么您可以使用jQuery将该信息放入页面1上的空DIV中。 - Keith DC
Ajax涉及到很多方面。如果您想使用jQuery等库,可以查看:http://api.jquery.com/jQuery.post/ - Keith DC

0

当用户点击返回按钮时,将以下代码添加到显示为离线的页面中:

<?php
 session_start();
 header_remove("Expires");
 header_remove("Cache-Control");
 header_remove("Pragma");
 header_remove("Last-Modified");
?>

0
一种方法是通过Ajax将Formdata提交到远程脚本,如果查询返回成功,则可以跳转到“感谢您”页面。这样用户就可以点击返回按钮,而不会弹出“重新加载”请求。
希望这个想法能帮到你。

点击“返回”按钮后,page1.php将再次运行ajax代码,而无需点击“提交”按钮,因为page1.php具有缓存...所以我认为ajax也无法解决这个问题... - zac1987

-1
创建一个会话,就像这里所示
你应该在每个页面使用会话并验证用户,你会惊讶于SESSION的工作方式!令人惊异!

请提供一个简短的示例,而不仅仅是链接到另一个网站,因为链接可能随着时间的推移而失效。 - thecodesmith_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接