Избегая повторной отправки формы на 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, данные записи все еще будут там.

Есть идеи?

Author: code-jaff, 2009-04-06

10 answers

Ваш метод мог бы работать теоретически, но есть гораздо более простой способ.

После успешной отправки формы выполните перенаправление. Неважно, куда, но это очистит $_POST.

header('Location: http://www.example.com/form.php');

В вашем случае это звучит так, как будто вы хотите перенаправить на страницу, на которой вы уже находитесь. Добавьте параметр $_GET к URL-адресу, если вы хотите отобразить сообщение с подтверждением.

Надеюсь, это поможет,

Том

 39
Author: Tom Wright, 2009-04-06 18:12:49

Решением является шаблон, обычно известный как Сообщение/Перенаправление/Получение

 9
Author: David Snabel-Caunt, 2009-04-06 18:45:33

Лучший способ обработки форм - использовать самостоятельную отправку и перенаправление. Что-то вроде этого:

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');
}
 6
Author: Michael Wales, 2009-04-06 18:12:25

Вы можете переписать свою форму-отправить в AJAX-способ. Если вам нужно показать HTML-контент, верните его в формате JSON и вставьте с помощью JavaScript (например, jQuery.)

 2
Author: ShiftedReality, 2014-10-17 05:32:32

Я решил эту проблему (на php) с помощью:

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

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

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

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

  4. После любого из 3a/3b перенаправление на страницу результатов с заголовком ('Местоположение: http://mydomain.com/mypage')

Результат:
никаких действий по повторной отправке для кнопки обновления/возврата и только предупреждение о повторной отправке при двойном нажатии кнопки возврата (но без повторной отправки)

 1
Author: Paul, 2011-12-19 11:11:25

Используйте расположение заголовка после успешного действия после публикации

header('Location: '.$_SERVER['HTTP_REFERER']);
 1
Author: Mehmet Ali Uysal, 2013-05-23 13:47:46

Это работает для меня, если я использую либо заголовок(), либо выход() в конце своего кода, например, после сохранения некоторых данных.

 1
Author: Misterk, 2015-09-13 03:09:28

Лучший метод, который я нашел, - это использование javascript и css. Заголовок обычного метода перенаправления php ('Местоположение: 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;

Тег стиля важен, иначе пользователю может показаться, что страница загружена дважды. Если мы используем тег стиля с отображением тела нет, а затем обновите страницу, тогда пользовательский интерфейс будет таким же, как заголовок php ('Местоположение: ....);

Надеюсь, это поможет:)

 1
Author: Ajith, 2017-06-23 12:30:11

Перенаправление заголовка после публикации необходимо, но недостаточно.

На стороне PHP после успешной отправки формы выполните перенаправление. Например, заголовок ('Местоположение: http://www.example.com/form.php');

Но этого недостаточно. Некоторые пользователи нажимают ссылки дважды (двойной клик). Требуется JavaScript, который отключил бы кнопку отправки после первого нажатия.

 0
Author: Mangirdas Skripka, 2011-11-27 16:44:19

Попробуйте мой собственный, возможно, это не лучшее решение (сделано быстро), но я протестировал его, и он работает. Протестировано на 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>
 0
Author: Adrian Rybka, 2018-02-02 21:48:39