我有一个向SQL表提交文本的简单表单。问题在于,在用户提交文本之后,他们可以刷新页面并再次提交数据,而无需再次填写表单。我可以在文本提交后将用户重定向到另一个页面,但我希望用户停留在同一页面上。
我记得我读过一些关于给每个用户一个唯一的会话id,并将其与另一个值进行比较,这解决了我所遇到的问题,但我忘记了它在哪里。
我有一个向SQL表提交文本的简单表单。问题在于,在用户提交文本之后,他们可以刷新页面并再次提交数据,而无需再次填写表单。我可以在文本提交后将用户重定向到另一个页面,但我希望用户停留在同一页面上。
我记得我读过一些关于给每个用户一个唯一的会话id,并将其与另一个值进行比较,这解决了我所遇到的问题,但我忘记了它在哪里。
当前回答
使用Post/Redirect/Get模式。http://en.wikipedia.org/wiki/Post/Redirect/Get
对于我的网站,我将在cookie或会话中存储消息,在发布后重定向,读取cookie/会话,然后清除该会话或cookie变量的值。
其他回答
插入到数据库后,调用unset()方法清除数据。
设置($ _POST);
为防止刷新数据插入,请在记录插入后将页面重定向到同一页或不同页。
头(地点:。$ _SERVER [' PHP_SELF ']);
对我有用的是:
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>
我找到了下一个变通办法。您可以通过操作历史对象在处理POST请求后转义重定向。
你有一个HTML表单
<form method=POST action='/process.php'>
<input type=submit value=OK>
</form>
当你在你的服务器上处理这个表单时,你不是重定向用户到/the/result/页面,而是像这样设置Location头:
$cat process.php
<?php
process POST data here
...
header('Location: /the/result/page');
exit();
?>
处理post数据后,呈现小的<脚本>和result/ the/result/page
<?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:
没有重定向 当你刷新页面时没有rePOST数据(F5) 当你通过浏览器历史导航到上一页/下一页时,没有rePOST
UPD
作为另一个解决方案,我要求Mozilla FireFox团队允许用户设置NextPage头,它将像Location头一样工作,使post/redirect/get模式过时。
简而言之。当服务器处理表单POST数据成功时:
设置NextPage头而不是位置 呈现POST表单数据处理的结果,就像在POST /redirect/ GET模式中呈现GET请求一样
浏览器依次看到NextPage头:
调整窗口。位置与NextPage值 当用户刷新页面时,浏览器将协商GET请求NextPage而不是rePOST表单数据
我认为这将是极好的,如果实施,不是吗?=)
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
}
我还想指出,您可以使用javascript方法window.history.replaceState来防止在刷新和返回按钮时重新提交。
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
这里的概念证明:https://dtbaker.net/files/prevent-post-resubmit.php(链接不再工作)
我仍然推荐Post/Redirect/Get方法,但这是一个新颖的JS解决方案。