Избегание повторной отправки формы в php при нажатии f5
-
05-09-2019 - |
Вопрос
У меня есть следующий код на моем сайте (с использованием 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 по умолчанию равно false, но меняется на true после успешной отправки формы.Переменные smarty title и desc используются в шаблоне для сохранения содержимого формы на случай ошибки пользователя и необходимости изменить то, что он ввел.
Если форма отправлена успешно, она устанавливает bln_added = true , поэтому второй бит кода должен не только очистить поля формы, но и опустошить $_POST.Но если я нажму f5, данные post все еще будут там.
Есть какие-нибудь идеи?
Решение
Теоретически ваш метод мог бы сработать, но есть гораздо более простой способ.
После успешной отправки формы выполните перенаправление.Неважно, куда, но это очистит $_POST .
header('Location: http://www.example.com/form.php');
В вашем случае это звучит так, как будто вы хотите перенаправить на страницу, на которой вы уже находитесь.Добавьте параметр $_GET к URL-адресу, если вы хотите отобразить сообщение с подтверждением.
Надеюсь, это поможет,
Том
Другие советы
Решением является шаблон, широко известный как Опубликовать / Перенаправить / Получить
Лучший способ обработки форм - это использовать самоподачу и перенаправление.Что- то вроде этого:
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.
Используя Фреймворк 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');
}
Вы можете переписать свою форму отправки в AJAX-way.Если вам нужно отобразить HTML-контент, верните его в формате JSON и вставьте с помощью JavaScript (например, jQuery).)
Я решил это (на php) с помощью:
в форму добавьте уникальный идентификатор (id+счетчик), не основанный на времени () (!!!)
опубликовать в отдельный файл (postform.php), который проверял наличие сеанса с этим уникальным идентификатором
a) если сеанс с уникальным идентификатором НЕ был найден:опубликуйте в базе данных и заполните сеанс уникальным идентификатором
б) если был найден сеанс с уникальным идентификатором:ничего не делай
после любого перенаправления 3a / 3b на страницу результатов с заголовком ('Location: http://mydomain.com/mypage')
Результатом является:
никаких действий по повторной отправке при обновлении / обратной кнопке и только предупреждение о повторной отправке при двойном нажатии кнопки обратной отправки (но никаких действий по повторной отправке)
Используйте расположение заголовка после успешного действия публикации
header('Location: '.$_SERVER['HTTP_REFERER']);
У меня это работает, если я использую либо header(), либо exit() в конце моего кода, например, после сохранения некоторых данных.
Лучший метод, который я нашел, - это использование javascript и css.Заголовок обычного метода перенаправления php('Location: http://www.yourdomain.com/url);будет работать, но это вызовет предупреждение " Warning:Невозможно изменить информацию заголовка - заголовки уже отправлены" в разных фреймворках и cms, таких как wordpress, drupal и т.д.Итак, мое предложение состоит в том, чтобы следовать приведенному ниже коду
echo '<style>body{display:none;}</style>';
echo '<script>window.location.href = "http://www.siteurl.com/mysuccesspage";</script>';
exit;
Тег style важен, иначе пользователю может показаться, что страница загружена дважды.Если мы используем тег style с body display none , а затем обновим страницу , то пользовательский интерфейс будет таким же , как в заголовке php('Location:....);
Я надеюсь, что это поможет :)
Перенаправление заголовка после публикации необходимо, но недостаточно.
На стороне PHP после успешной отправки формы выполните перенаправление.Например.заголовок ('Местоположение: http://www.example.com/form.php');
Но этого недостаточно.Некоторые пользователи нажимают на ссылки дважды (doubleclick).Требуется JavaScript, который отключал бы кнопку отправки после первого нажатия.
Попробуйте мой собственный, возможно, это не лучшее решение (делается быстро), но я протестировал его, и оно работает.Протестировано на Chrome. Нажмите, чтобы увидеть, как это выглядит БР
<?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>