Избегание повторной отправки формы в php при нажатии f5

StackOverflow https://stackoverflow.com/questions/722547

  •  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) с помощью:

  1. в форму добавьте уникальный идентификатор (id+счетчик), не основанный на времени () (!!!)

  2. опубликовать в отдельный файл (postform.php), который проверял наличие сеанса с этим уникальным идентификатором

  3. a) если сеанс с уникальным идентификатором НЕ был найден:опубликуйте в базе данных и заполните сеанс уникальным идентификатором

    б) если был найден сеанс с уникальным идентификатором:ничего не делай

  4. после любого перенаправления 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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top