Welcome to php club

PHP FAQ from PHPclub.ru: ProblemsLocations ...

Начало | Каталог | Изменения | НовыеКомментарии | Вам запрещён доступПользователи | Вам запрещён доступРегистрация | Вход:  Пароль:  

Php Problems

Как предотвратить повторную отправку данных на сервер при нажатии “refresh” в браузере?

(оно же «как избавиться от текста 'The page cannot be displayed' при нажатии в браузере 'назад' после POST-запроса?»)

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


<?php
    
// файл 1.php
    // достаем данные из базы
?>


<form action = "2.php" method = "post">
// рисуем элементы формы
</form>


<?php
    
// файл 2.php
    // кладем данные в базу
    
echo "спасибо, что Вы есть";
?>


Данные действительно прекрасно добавляются/обновляются и, не считая проблем со слешами и глобальными переменными (о которых можно почитать в других разделах FAQ, например, тут), все вроде бы нормально. Но тут надоедливые юзеры после добавления данных жмут кнопку “refresh” (зачем? не понятно) и спрашивают: а что это у меня за окошко всплыло и что мне теперь жать? Но это не единственная проблема. Что делать если человек не заполнил какое-либо обязательное поле? Например, email, а он нам очень нужен. Как мы теперь из файла 2.php передадим данные обратно в файл 1.php? Заставлять пользователя заново вводить все данные? Эдак мы всех пользователей растеряем. На самом деле все не так уж страшно, все проблемы решаются одним махом. Мы оба файла сольем в один, и, главное, после добавления данных, «попросим» браузер запросить эту страницу снова. «Попросить» мы можем, отправив браузеру HTTP зпголовок с полем Location. Получив такой заголовок от сервера, браузер запросит страницу указанную в заголовке. Таким образом, при refresh, браузер уже не будет задавать вопрос о повторной отправке данных.


<?
if (isset($_POST['posted'])) {
    
// проверка данных 
    
if (данные хорошие) {
        
/* 
          записываем данные
        */
        /*Заставляем браузер запросить нашу страницу с формой повторно*/
        
header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?ok'); // любо на другой скрипт
        /*
            желательно при этом помнить о пользователях, у которых 
            отключены куки и которые могут потерять идентификатор сессии,
            но это отдельный разговор
        */
        
exit;
    } 
    else {
        echo 
"ошибка!!!";
    }
    
}
elseif (isset(
$_GET['ok'])) {
    echo 
"спасибо, что Вы есть";
}
else
{
    
// выбираем данные из бызы
}
?>
<form action = "<?=$_SERVER["PHP_SELF"]?>" method = "post">
<input type = "hidden" name = "posted" value = "1">
// рисуем форму
</form>


Вот и все. Есть, конечно, множество вариаций на эту тему. После записи данных можно переходить на другой скрипт, который будет рисовать эти данные в красивом виде или на какой-нибудь список. Некоторые вместо проверке hidden-поля проверяют метод пришедшего запроса. Но суть от этого не меняется.



 
Комментариев нет. [Показать комментарии/форму]