Перезагрузить / обновить страницу в браузере без повторной отправки формы?

#php #forms #refresh #reload

#php #формы #обновить #перезагрузить

Вопрос:

У меня есть форма на странице php, которая отправляется на ту же страницу. Я заметил, что если я перезагружаю / обновляю страницу, форма повторно отправляется. Как мне написать код, чтобы избежать этого самым простым способом?

Комментарии:

1. Вы можете попробовать перенаправить на страницу обновления.

2. en.wikipedia.org/wiki/Post/Redirect/Get

3. Вы не можете… все дело в том, что пользовательский ввод мог потребоваться для создания страницы, на которой вы находитесь в данный момент. Я бы посоветовал оставить это поведение в покое, если у вас нет конкретной причины его изменить. Если вы это сделаете, вы можете сделать то, что предлагает Blender, и перейти на промежуточную страницу или отправить свои данные через AJAX перед переходом на следующую страницу.

4. Вы также можете сгенерировать случайную строку в скрытом вводе, поместить ее в файл cookie (или сеанс), убедиться, что строка соответствует значению файла cookie, и уничтожить ее при первой отправке формы. Итак, если пользователь отправит те же данные в следующий раз, проверка завершится неудачно, и вы узнаете, что форма уже отправлена. Но для этого требуются файлы cookie, поэтому, если вы можете просто перенаправить, это лучший выбор.

5. Вы можете использовать AJAX для асинхронной отправки формы, если хотите оставаться на той же странице. Кроме этого, большинство решений являются грубыми и на самом деле являются взломом, а не реальным решением. Отправка данных POST при обновлении — это нормальное поведение браузера, и есть причина, по которой браузеры оставляют это так.

Ответ №1:

Одна из возможностей заключается в реализации подхода post-redirect-get.

Проще говоря, запрос POST никогда не будет доставлен в браузер. Вместо этого вы выполняете все необходимые действия и сохраняете необходимую информацию в сеансе, а затем делаете перенаправление с кодом 303.

 $page = 'show_result.php';
header('Location: '.$page, true, 303);
exit;
  

Делая это таким образом, браузер покажет «show_result.php » страница (запрос на получение) вместо страницы, запрошенной с помощью POST. Это также страница, которая добавляется в историю, поэтому обновление и использование кнопки «Назад» никогда не будут выполнять другой запрос POST. В качестве приятного побочного эффекта вы избавляетесь от предупреждений браузера о повторной отправке данных, обычно пользователь все равно не может решить, что делать дальше.

Я думаю, что самая большая проблема с этим подходом заключается в том, что вам нужен сеанс для хранения сообщений об ошибках, это означает, что вы должны полагаться на файлы cookie. Если вы не сделаете перенаправление для отображения ошибок, браузер покажет предупреждение о повторной отправке данных.

Комментарии:

1. Post-redirect-get не требует сеансов, и я не уверен, что вы подразумеваете под «POST-запрос никогда не будет доставлен в браузер»

2. @j08691 — На каждый запрос POST будет отвечать перенаправление (код 303). Браузер получает этот ответ и запускает новый запрос GET, который показывает результат первого запроса. Сеанс необходим, когда запрос POST обнаруживает неверный пользовательский ввод, и следующий запрос GET должен отображать сообщение об ошибке и последний пользовательский ввод.

Ответ №2:

Это предполагает много вещей, но, возможно, это то, что вы ищете:

 if ($_POST)
{
    $success = false;

    /*
     * if all goes OK managing POST data make $success = true;
     * 
     */

    if ($success)
    {
        // this will redirects to your original
        // form's page but using GET method
        // so re-submitting will be no possible
        header("location: {$_SERVER['PHP_SELF']}");
        exit;
    }
}
  

Комментарии:

1. PHP_SELF удалит любой параметр GET. Используйте REQUEST_URI для их сохранения.

Ответ №3:

Согласно стандарту HTTP, вы должны заставить браузер выполнять запрос GET после отправки POST.
Вот пример эскиза для обработки формы:

 <?  
if ($_SERVER['REQUEST_METHOD']=='POST') {  

  $err = array();
  //performing all validations and raising corresponding errors
  if (empty($_POST['name']) $err[] = "Username field is required";  
  if (empty($_POST['text']) $err[] = "Comments field is required";  

  if (!$err) {  
    //if no errors - saving data and redirect
    header("Location: ".$_SERVER['PHP_SELF']);
    exit;
  }  else {
    // all field values should be escaped according to HTML standard
    foreach ($_POST as $key => $val) {
      $form[$key] = htmlspecialchars($val);
    }
} else {
  $form['name'] = $form['comments'] = '';  
}
include 'form.tpl.php';
?>