it-swarm.com.ru

Запрет повторной отправки формы при нажатии кнопки назад

Я искал много сообщений здесь и в других местах, но не могу найти решение своей проблемы. У меня есть страница, которая отображает записи базы данных: database.php. Эти записи могут быть отфильтрованы с помощью формы. Когда я фильтрую их и показываю только те, которые меня интересуют, я могу щелкнуть запись (в виде ссылки), которая приводит меня на эту страницу записей (через php GET). Когда я нахожусь на этой странице записей (то есть "view.php? Id = 1") и нажимаю кнопку "Назад" (back to database.php), форма фильтра требует подтверждения повторной отправки формы. Есть ли способ предотвратить это?

вот некоторые (упрощенные) примеры кода:

Database.php:

<form>
    <select>
        <option>1</option>
        <option>2
        <option>
    </select>
    <input type="submit" name="apply_filter" />
</form>
<?php
if ( isset( $_POST[ "apply_filter" ] ) ) { // display filtered entries
    $filter = $_POST[ "filter" ];
    $q = "Select * from table where col = '" . $filter . "'";
    $r = mysql_query( $q );
} else { // display all entries
    $q = "Select * from table";
    $r = mysql_query( $q );
}
while ( $rec = mysql_fetch_assoc( $r ) ) {
    echo "<a href='view.php?id=" . $rec[ "id" ] . "'>" . $rec[ "name" ] . "</a><br />"; // this is where the link to the view.php page is...
}
?>

Теперь, как уже упоминалось, если я нажимаю на ссылку, я перехожу на «view.php? Id = что угодно». На этой странице я просто получаю идентификатор из URL для отображения этой единственной записи:

view.php:

<?php
$id = $_GET[ "id" ];
$q = "Select * from table where id = '" . $id . "'";
$r = mysql_query( $q );
while (  ) {
    // display entry
}

?>

Если я теперь нажму кнопку «Назад», форма для database.php (та, которая используется для фильтрации результатов БД) требует подтверждения для повторной отправки. Это не только раздражает, но и бесполезно для меня.

Как я могу это исправить? Я надеюсь, что примеры кода и объяснение моей проблемы достаточно. Если нет, дайте мне знать, и я постараюсь уточнить.

20
user1889382

Я знаю, что этот вопрос старый, но имея эту проблему сам, я обнаружил две строки, которые работают:

header("Cache-Control: no cache");
session_cache_limiter("private_no_expire");
23
Ryan Konkolewski

Есть два способа сделать это. Простой и трудный путь.

Независимо от способа, когда вы имеете дело со страницей на основе состояния (используя $_SESSION), что вы должны делать, чтобы ваши страницы были «живыми» и находились под вашим контролем, это предотвращало кэширование всех страниц, как это:

<?php
//Set no caching
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
header("Cache-Control: no-store, no-cache, must-revalidate"); 
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>

Сложный путь заключается в создании идентификатора и его сохранении где-то на странице в виде скрытого ввода или файла cookie &_SESSION. Затем вы сохраняете тот же идентификатор на сервере, что и $_SESSION. Если они не совпадают, серия предварительно запрограммированных операторов типа ifelse приводит к тому, что ничего не происходит с повторной отправкой страницы (это то, что она пытается сделать, когда вы нажимаете назад).

Самый простой способ - просто перенаправить пользователя обратно на страницу отправки формы, если форма была успешно отправлена, например:

header('Location: http://www.mydomain.com/redirect.php');

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

8
Phillip Berger

Одна вещь, которая может помочь, - это заставить вашу форму фильтра использовать метод GET вместо POST.

Браузеры, как правило, предотвращают повторную отправку ввода POST, чего не делают при использовании ввода GET. Кроме того, это позволит пользователям ссылаться на вашу страницу с помощью фильтра.

3
tanios

Альтернативное решение, которое также работает, если/когда страница перезагружается, включает проверку оригинальности сообщения с помощью $ _SESSION. В двух словах, проверьте наличие уникальной или случайной строки.

В форме добавьте элемент ввода со значением, установленным с помощью Rand () или microtime ():

<input type="hidden" name="formToken" value="<?php echo microtime();?>"/>

А затем оберните функцию PHP, чтобы проверить и проанализировать данные формы в блоке if:

if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){
       $_SESSION['formToken'] = $_POST['formToken'];
      /*continue form processing */
}
0
SilentStone

Я использовал ответ в Как я могу определить, попал ли пользователь на страницу с помощью кнопки «Назад»? чтобы определить, было ли посещение вызвано нажатием кнопки «Назад» в браузере, а затем, если это так, я использовал JavaScript для перезагрузки страницы. Когда страница перезагружается, мой код уже обрабатывает соответствующие проверки, чтобы убедиться, что форма никогда не отправляется дважды. Важной частью в моем случае было принудительное обновление страницы при повторном посещении формы после нажатия кнопки «Назад» в браузере. Это мой код в URL, где я хотел применить эту проверку:

<script type="text/javascript">
    if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
        location.reload();
    }
</script>
0
Jaime Montoya