PHP阻止F5重新提交|不重定向
我想防止F5在用户通过Post方法发送表单数据时重新提交PHP阻止F5重新提交|不重定向,php,html,post,form-submit,Php,Html,Post,Form Submit,我想防止F5在用户通过Post方法发送表单数据时重新提交 我不希望用户被重定向到同一个页面 我需要在正确提交时闪现消息 提交后,清洁所有的$\u帖子 我不能使用javascript,只能使用PHP 因此,首先,我有一个页面,其中有一个表单可以提交信息/数据,当正确提交时,我想闪现一条带有正面反馈的消息,并清除$u POST['vars']中的所有数据 PHP代码: <?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { $error=
- 我不希望用户被重定向到同一个页面李>
- 我需要在正确提交时闪现消息李>
- 提交后,清洁所有的$\u帖子
- 我不能使用javascript,只能使用PHP李>
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$error= '';
if (!$_POST['name']) {
$error.= '- Introduza o seu Nome.<br>';
}
if (!$_POST['email']) {
$error.= '- Introduza o seu Email.<br>';
}
if (!$_POST['message']) {
$error.= '- Introduza a sua mensagem.<br>';
}
if (empty($_POST['check'])) {
$error.= '- Por favor, confirme que é um humano.<br>';
}
if ($error) {
$result="Temos erros no formulário. Por favor corriga os seguinte(s):<br> $error";
} else {
mail("email@email", "Mensagem de Contato", "Nome: ".$_POST['name']. "Email: ". $_POST['email'] . "Mensagem: " . $_POST['message'] );
$result='A sua mensagem foi enviada. Obrigado<br>';
}
}
?>
HTML:
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>Formulário de Contato</h1>
<p>Envie mensagem pelo formulário em baixo</p>
<?php if (isset($_POST['submit'])) {
echo $result;
}
?>
<br>
<form method="post" action="" role="form">
<div class="form-group">
<input type="text" name="name" class="form-control" placeholder="Coloque aqui o seu nome" value="<?php
if (isset($_POST['name'])) {
echo $_POST['name'];
}
?>">
</div>
<div class="form-group">
<input type="email" name="email" class="form-control" placeholder="O seu email" value="<?php
if (isset($_POST['email'])) {
echo $_POST['email'];
}
?>">
</div>
<div class="form-group">
<textarea name="message" name="message" class="form-control" cols="30" rows="10" placeholder="Escreva a sua mensagem"><?php
if (isset($_POST['message'])) {
echo $_POST['message'];
}
?></textarea>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="check" >Confirma que é humano.
</label>
</div>
<div align="center">
<input type="submit" name="submit" class="btn btn-secondary" value="Enviar Mensagem">
</div>
</div>
</form>
</div>
</div>
</div>
孔塔托河
埃米·拜克索的嫉妒
让我们看看这些要求:
- 我不能使用javascript,只能使用PHP李>
- 你不想重定向
因此,当浏览器收到表单时,它只能将表单提交给PHP。不允许使用Javascript/AJAX恶作剧。因此,按F5将是不可预防的
“Clearing$\u POST”表示无任何内容-您不能从服务器修改可能由浏览器(重新)发布的数据,除非浏览器已经信任您并下载了相应的Javascript
一旦交易完成,就可以远程更改\u POST
,这将是一个可怕的安全漏洞(想想电子支付)
但您所要做的就是不要重复操作。要执行此操作,无需清除$\u POST
。我们唯一能做的就是识别重新提交的邮件并区别对待(在这种情况下,不再发送邮件);这就是我们需要做的
我们通过在表单中添加一个唯一的、不可重用的ID来实现这一点,例如,当页面使用PHP创建时,由uniqueid()
生成:
<input type="hidden" name="nonce" value="0cf8059606c73ab872cd8e0064" />
或者,我们可以简单地运行测试,如果测试不成功,我们就死掉:
if (in_array($_POST['nonce'], $_SESSION['posts'])) {
die('Não atualize a pagina. Click <a href="/">aqui</a> para voltar para a home.');
}
此时,当您收到nonce时
1. it is not in the database, and there is POST.
- do whatever needs to be done and update the database accordingly.
2. is in the database, and there is a POST.
- it is a resubmission. Ignore it, or display an error
3. is not in the database, and there is no POST.
- it's a prankster, or a database error.
4. is in the database, and there is no POST.
- is a bookmark. Display the success page as in (1).
如果用户按F5,则为案例(2)。如果他将页面另存为书签,URL中的nonce来自最近完成的提交,因此用户在案例(1)中,并设置为按照案例(4)进行操作。preventDefault()是查找F5按键的javascript函数的一部分,停止刷新并按需要提交,然后发送通知;如果你不介意我问你,是什么阻止你使用javascript?我想在没有javascript的情况下这样做,只是为了测试是否可以做到。我搜索了很多,没有发现任何只使用php的例子(没有使用php重定向)可能重复伟大的解决方案,我唯一的问题是,他特别要求“提交后清理所有的$_帖子”,这对我来说并不清楚-我可以忽略_帖子(或者,是的,清除它),但是“提交后”POST数据不再存在。我无法从PHP服务器更改浏览器客户端的历史记录。那么“干净的帖子”是什么意思呢?提交后,我在一个不同的页面上(即使它是与之前相同的HTML)。我不能预先填充输入字段的值,下一次提交将是新的。
if (array_key_exists('nonce', $_POST)) {
$nonce = $_POST['nonce'];
unset($_POST['nonce']); // for transparency with extant code
if (array_key_exists($nonce, $_SESSION['securePosts'])) {
if ($_SESSION['securePosts'][$nonce]) {
$error = false;
// Punch the ticket so it can't be reused
$_SESSION['securePosts'][$nonce] = false;
} else {
$error = 'FORM resubmitted';
}
} else {
$error = 'Someone sent a fake FORM or a FORM from an expired session';
}
}
if (!$error) {
// We can treat $_POST as legit.
// Here the code that "does something".
}
$uniqueid = secureUniqueId();
$_SESSION['securePosts'][$uniqueid] = true; // Ready to be triggered
print "<input type=\"hidden\" name=\"nonce\" value=\"{$uniqueid}\" />";
// If no error, empty DIV
print "<div id=\"error\">{$error}</div>";
<form method="POST" action="?nonce={$nonce}">
nonce results (in separate columns)
eb72ab1736a32... invoice=1234,amount=32,...
1. it is not in the database, and there is POST.
- do whatever needs to be done and update the database accordingly.
2. is in the database, and there is a POST.
- it is a resubmission. Ignore it, or display an error
3. is not in the database, and there is no POST.
- it's a prankster, or a database error.
4. is in the database, and there is no POST.
- is a bookmark. Display the success page as in (1).