Как избежать повторной отправки формы в php при нажатии f5
У меня есть следующий код на моем сайте (используя 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, данные поста все еще там.
Есть идеи?
10 ответов
Ваш метод может работать теоретически, но есть гораздо более простой способ.
После успешной отправки формы выполните перенаправление. Неважно, куда, но это очистит $_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-способ. Если вам нужно показать HTML-контент, верните его в JSON-формате и вставьте с помощью JavaScript(например, jQuery.)
Я решил это (в php):
в форме добавьте уникальный идентификатор (id+counter), не основанный на time() (!!!)
отправить в отдельный файл (postform.php), который проверил сеанс с этим уникальным идентификатором
а) если сеанс с уникальным идентификатором НЕ был найден: отправить в базу данных и заполнить сеанс с уникальным идентификатором
б) если был найден сеанс с уникальным идентификатором: ничего не делать
после перенаправления 3a/3b на страницу результатов с заголовком ('Location: http://mydomain.com/mypage')
Результат:
не выполнять повторные действия для кнопки "Обновить / Backbutton" и только предупреждение о повторной отправке для кнопки двойного щелчка (но без повторного действия)
Это работает для меня, если я использую header() или exit() в конце моего кода, например, после сохранения некоторых данных.
Лучший метод, который я нашел, - это использование javascript и css. Общий заголовок метода перенаправления php ('Location: http://www.yourdomain.com/url); будет работать, но это вызовет предупреждение "Предупреждение: невозможно изменить информацию заголовка - заголовки уже отправлены" в различных средах и CMS, таких как WordPress, Drupal и т. д. Поэтому я предлагаю следовать приведенному ниже коду
echo '<style>body{display:none;}</style>';
echo '<script>window.location.href = "http://www.siteurl.com/mysuccesspage";</script>';
exit;
Тег стиля важен, иначе пользователь может почувствовать, что страница загружена дважды. Если мы используем тэг style с отсутствующим отображением тела, а затем обновляем страницу, пользовательский интерфейс будет похож на заголовок php ('Location: ....);
Я надеюсь, это поможет:)
Использовать местоположение заголовка после успешного завершения действия
header('Location: '.$_SERVER['HTTP_REFERER']);
Ответ , который вы ищете, - это волшебный лайнер:
header('Location: '.$_SERVER['HTTP_REFERER']);
например
if(isset['submit']){
//insert database
header('Location: '.$_SERVER['HTTP_REFERER']);
}
Перенаправление заголовка после публикации необходимо, но недостаточно.
На стороне PHP после успешной отправки формы выполните перенаправление. Например. заголовок ('Location: http://www.example.com/form.php');
но этого не достаточно. Некоторые пользователи нажимают на ссылки дважды (двойной щелчок). Требуется JavaScript, который отключит кнопку отправки после первого клика.
Попробуйте свой собственный, возможно, это не лучшее решение (сделано быстро), но я протестировал его, и оно работает. Проверено на Chrome. Нажмите, чтобы увидеть, как это выглядит BR
<?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>