Как предотвратить повторное заполнение формы при обновлении страницы (F5/CTRL + R)

У меня есть простая форма, которая отправляет текст в мою таблицу SQL. Проблема в том, что после того, как пользователь отправит текст, они могут обновить страницу, и данные будут отправлены снова, не заполнив форму снова. Я мог перенаправить пользователя на другую страницу после отправки текста, но хочу, чтобы пользователи оставались на одной странице.

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

Ответ 1

Используйте шаблон Post/Redirect/Get. http://en.wikipedia.org/wiki/Post/Redirect/Get

На моем веб-сайте я сохраню сообщение в cookie или сеансе, перенаправляю после публикации, читаю cookie/session и затем очищаю значение этой сессии или переменной cookie.

Ответ 2

Вам действительно нужно использовать шаблон Post Redirect Get для обработки этого, но если вы каким-то образом оказались в позиции, где PRG не является жизнеспособным (например, сама форма включена, предотвращая переадресацию), вы можете использовать некоторые из параметры запроса для создания строки на основе содержимого, а затем убедитесь, что вы еще не отправили ее.

//create digest of the form submission:

    $messageIdent = md5($_POST['name'] . $_POST['email'] . $_POST['phone'] . $_POST['comment']);

//and check it against the stored value:

    $sessionMessageIdent = isset($_SESSION['messageIdent'])?$_SESSION['messageIdent']:'';

    if($messageIdent!=$sessionMessageIdent){//if its different:          
        //save the session var:
            $_SESSION['messageIdent'] = $messageIdent;
        //and...
            do_your_thang();
    } else {
        //you've sent this already!
    }

Ответ 3

  • Используйте заголовок и перенаправляйте страницу.

    header("Location:your_page.php"); Вы можете перенаправить на ту же страницу или на другую страницу.

  • Unset $_POST после вставки его в базу данных.

    unset($_POST);

Ответ 4

Когда форма обрабатывается, вы перенаправляетесь на другую страницу:

... process complete....
header('Location: thankyou.php');

вы также можете перенаправить на ту же страницу.

если вы делаете что-то вроде комментариев и хотите, чтобы пользователь оставался на одной странице, вы можете использовать Ajax для обработки отправки формы

Ответ 5

Довольно верный способ - реализовать уникальный идентификатор в сообщении и кэшировать его в

<input type='hidden' name='post_id' value='".createPassword(64)."'>

Затем в коде выполните следующее:

if( ($_SESSION['post_id'] != $_POST['post_id']) )
{
    $_SESSION['post_id'] = $_POST['post_id'];
    //do post stuff
} else {
    //normal display
}

function createPassword($length)
{
    $chars = "abcdefghijkmnopqrstuvwxyz023456789";
    srand((double)microtime()*1000000);
    $i = 0;
    $pass = '' ;

    while ($i <= ($length - 1)) {
        $num = rand() % 33;
        $tmp = substr($chars, $num, 1);
        $pass = $pass . $tmp;
        $i++;
    }
    return $pass;
}

Ответ 6

вы можете использовать форму повторной отправки через переменную сеанса Как

сначала вам нужно установить rand() в текстовое поле и $_SESSION ['rand'] на странице формы

<form action="" method="post">
  <?php
   $rand=rand();
   $_SESSION['rand']=$rand;
  ?>
 <input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
   Your Form Other Field 
 <input type="submit" name="submitbtn" value="submit" />
</form>

После проверки $_SESSION ['rand'] с текстовым полем $_POST ['randcheck'] значение Как

         if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
          {
         //Your Code here
         }

Ответ 7

Просто переадресовывайте его на ту же страницу после использования данных формы, и он работает. Я пробовал это.

header('location:yourpage.php');

Ответ 8

Утонченная версия сообщения Moob. Создайте хэш POST, сохраните его как файл cookie сеанса и сравните хеширования каждого сеанса.

// Optionally Disable browser caching on "Back"
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Expires: Sun, 1 Jan 2000 12:00:00 GMT' );
header( 'Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT' );

$post_hash = md5( json_encode( $_POST ) );

if( session_start() )
{
    $post_resubmitted = isset( $_SESSION[ 'post_hash' ] ) && $_SESSION[ 'post_hash' ] == $post_hash;
    $_SESSION[ 'post_hash' ] = $post_hash;
    session_write_close();
}
else
{
    $post_resubmitted = false;
}

if ( $post_resubmitted ) {
  // POST was resubmitted
}
else
{
  // POST was submitted normally
}

Ответ 9

После вставки его в базу данных вызовите метод unset(), чтобы очистить данные.

снята с охраны ($ _ POST);

Чтобы предотвратить обновление данных обновления, выполните перенаправление страницы на ту же страницу или на другую страницу после записи.

заголовок ( 'Location:'. $_ SERVER [ 'PHP_SELF']);

Ответ 10

В принципе, вам нужно перенаправить с этой страницы, но она все еще может стать проблемой, пока ваш интернет медленный (переадресация заголовка с сервера)

Пример базового сценария:

Нажмите кнопку отправки дважды

Способ решения

  • Клиентская сторона

    • Отключить кнопку отправки, когда клиент кликнет по ней.
    • Если вы используете JQuery: Jquery.one
    • Шаблон PRG
  • Серверная сторона

    • Использование дифференцированной временной отметки времени хэширования/метки времени при отправке запроса.
    • Символы Userequest. Когда основные нагрузки назначают временный запрос, который, если повторяется, игнорируется.

Ответ 11

Я нашел следующее обходное решение. Вы можете избежать перенаправления после обработки запроса POST, манипулируя history объектом.

Итак, у вас есть HTML-форма:

<form method=POST action='/process.php'>
 <input type=submit value=OK>
</form>

Когда вы обрабатываете эту форму на своем сервере, вы вместо перенаправления пользователя на /the/result/page настраиваете заголовок Location следующим образом:

$cat process.php
<?php 
     process POST data here
     ... 
     header('Location: /the/result/page');
     exit();
?>

введите описание изображения здесь

После обработки POST ed данных вы выполняете небольшие <script> и результат /the/result/page

<?php 
     process POST data here
     render the <script>         // see below
     render `/the/result/page`   // OK
?>

<script> вы должны сделать:

<script>
    window.onload = function() {
        history.replaceState("", "", "/the/result/page");
    }
</script>

Результат:

введите описание изображения здесь

как вы можете видеть, данные формы POST ed до process.php script.
Этот script процесс POST редактировать данные и рендеринг /the/result/page сразу с помощью

  • нет перенаправления
  • no re POST данные при обновлении страницы (F5)
  • no re POST при переходе к предыдущей/следующей странице через историю браузера

UPD

В качестве другого решения я прошу команду Mozilla FireFox, чтобы пользователи могли настроить заголовок NextPage который будет работать как заголовок Location и сделать шаблон post/redirect/get устаревшим.

Короче. Когда серверный процесс успешно сформирует POST данные:

  • Настройка NextPage вместо Location
  • Отобразить результат обработки данных формы POST, как это было бы сделать для запроса GET в шаблоне post/redirect/get

В свою очередь браузер просматривает заголовок NextPage:

  • Откорректируйте window.location с NextPage значением
  • Когда пользователь обновляет страницу, браузер будет согласовывать GET запрос NextPage вместо данных POST формы

Я думаю, что это было бы отлично, если бы реализовано, не так ли? =)

Ответ 12

Я также хотел бы указать, что вы можете использовать подход javascript, window.history.replaceState, чтобы предотвратить повторную отправку на кнопке обновления и возврата.

<script>
    if ( window.history.replaceState ) {
        window.history.replaceState( null, null, window.location.href );
    }
</script>

Доказательство концепции здесь: https://dtbaker.net/files/prevent-post-resubmit.php

Я бы по-прежнему рекомендовал подход Post/Redirect/Get, но это новое решение JS.

Ответ 13

Использование шаблона Post/Redirect/Get из ответа Keverw - хорошая идея. Однако вы не можете оставаться на своей странице (и я думаю, что это было то, о чем вы просили?) Кроме того, иногда может fail

Если веб-пользователь обновляется до завершения первоначальной отправки из-за задержки сервера, что приводит к дублированию запроса HTTP POST в некоторые пользовательские агенты.

Другой вариант - сохранить в сеансе, если текст должен быть записан в вашу базу данных SQL следующим образом:

if($_SERVER['REQUEST_METHOD'] != 'POST')
{
  $_SESSION['writeSQL'] = true;
}
else
{
  if(isset($_SESSION['writeSQL']) && $_SESSION['writeSQL'])
  {
    $_SESSION['writeSQL'] = false;

    /* save $_POST values into SQL */
  }
}

Ответ 14

Как предотвратить повторное заполнение формы php без перенаправления. Если вы используете $_SESSION (после session_start) и форму $_POST, вы можете сделать что-то вроде этого:

if ( !empty($_SESSION['act']) && !empty($_POST['act']) && $_POST['act'] == $_SESSION['act'] ) {
  // do your stuff, save data into database, etc
}

В вашей html-форме поставьте это:

<input type="hidden" id="act" name="act" value="<?php echo ( empty($_POST['act']) || $_POST['act']==2 )? 1 : 2; ?>">
<?php
if ( $_POST['act'] == $_SESSION['act'] ){
    if ( empty( $_SESSION['act'] ) || $_SESSION['act'] == 2 ){
        $_SESSION['act'] = 1;
    } else {
        $_SESSION['act'] = 2;
    }
}
?>

Итак, каждый раз, когда форма отправляется, создается новый акт, сохраняется в сеансе и сравнивается с постулатом post.

Ps: если вы используете форму Get, вы можете легко изменить все POST с помощью GET, и он тоже работает.

Ответ 15

Как говорили другие, невозможно использовать post/redirect/get. Но в то же время довольно легко сделать то, что вы хотите сделать на стороне сервера.

На странице POST вы просто проверяете ввод пользователя, но не действуете на нем, вместо этого вы копируете его в массив SESSION. Затем вы снова перенаправляетесь на главную страницу представления. Ваша основная страница отправки начинается с проверки, существует ли массив SESSION, который вы используете, и если это необходимо скопировать в локальный массив и отключить его. Оттуда вы можете действовать на нем.

Таким образом, вы выполняете всю свою основную работу один раз, достигая того, что хотите.

Ответ 16

Почему бы просто не использовать переменную $_POST['submit'] в качестве логического оператора, чтобы сохранить все, что есть в форме. Вы всегда можете перенаправить на ту же страницу (в случае их обновления, и когда они попадут в go back в браузере, переменная post post больше не будет установлена. Просто убедитесь, что ваша кнопка отправки имеет name и id of submit.