Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/18: Рейтинг темы: голосов - 18, средняя оценка - 5.00
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076

Как при обновлении страницы избежать повторной отправки POST запроса с передачей переменных в шаблон?

23.06.2020, 12:23. Показов 3829. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть страничка юзера, на ней форма изменения роли(админ/юзер). Реализовано на радиокнопках и кнопке подтверждения выбора.
При всех вариантах событий на страничку должно выводиться сообщение об успешной или неудачной операции.

Видел варианты - переадресовывать на ту же страничку. но я тогда не знаю, как правильно передавать сообщения в шаблон.
Пробовал делать unset, вижу. что при обновлении странички уже нет переменной $_POST['role'], но условие if(isset($_POST['role'])) не срабатывает
Сам обработчик:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
     * @param int $id
     * @throws DbException
     */
    public function roleControl(int $id)
    {
        $userById = User::getById($id);
        if (!empty($_POST)){
            if(isset($_POST['role'])){
                if ($userById->getRole() === $_POST['role']){
                    $success = 'This user role is already set as "'.$_POST['role'].'"';
                    unset($_POST['role']);
                    $this->view->renderHtml('users/user.php', ['changeResult' => $success, 'userById' => $userById,]);
                    return;
                }
                $role = $userById->changeAndSaveRole();
                $success = 'This user role is successfully changed to "'.$role.'"';
                unset($_POST['role']);
                $this->view->renderHtml('users/user.php', ['changeResult' => $success, 'userById' => $userById,]);
                return;
            }
            $success = 'You haven\'t choosen role option';
            $this->view->renderHtml('users/user.php', ['changeResult' => $success, 'userById' => $userById,]);
            return;
        }
    }
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.06.2020, 12:23
Ответы с готовыми решениями:

Повторение POST запроса при обновлении страницы
Доброе время суток, может кто-нибудь подсказать можно ли избавиться от повторного отправления POST запроса при обновлении страницы ? Тоесть...

Запретить повторную отправку POST запроса при обновлении страницы
Вопрос немного нубский... Но есть страница с формой, юзер вводит какие то данные, и при нажатии на кнопку происходит отправка POST...

Как избежать повторной отправки формы?
Пробовала после получения данных формы и их обработки header('Location: /file.php'); но выдает ошибку - Cannot modify header information -...

24
 Аватар для fanatikus
1932 / 1523 / 703
Регистрация: 17.11.2012
Сообщений: 6,585
23.06.2020, 12:36
Цитата Сообщение от СергейСереб Посмотреть сообщение
но я тогда не знаю, как правильно передавать сообщения в шаблон.
сессия
1
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076
23.06.2020, 13:19  [ТС]
Цитата Сообщение от fanatikus Посмотреть сообщение
сессия
Ок, вариант.
А почему не срабатывает условие, которое я описал выше? Переменная же удаляется из $_POST, я это явно вижу.
0
1306 / 998 / 232
Регистрация: 01.10.2018
Сообщений: 3,884
23.06.2020, 15:11
Цитата Сообщение от СергейСереб Посмотреть сообщение
но я тогда не знаю, как правильно передавать сообщения в шаблон.
Если сообщение без частных деталей, например имен файлов, можно добавлять код сообщения к адресу возврата, по которому выводить модифицированную страницу. Также не забывайте о динамическом вычислении, которое я упоминал в предыдущей теме. Например, вы можете передать только код, указывающий на необходимость вывода сообщения, а какое именно это будет сообщение, можно "вычислить" на месте

Добавлено через 5 минут
1) GET /setrole
2) POST /setrole
3) GET /setrole/info

Можно и на исходной форме отображать текущую роль, чтобы не делать модификацию

Добавлено через 5 минут
Достаточно новым состоянием радиокнопок показать, что действие завершилось успешно

А модификатор можно использовать для ошибки.
0
23.06.2020, 17:08

Не по теме:

Ошибся при чтении вопроса

0
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076
23.06.2020, 17:44  [ТС]
Цитата Сообщение от estic Посмотреть сообщение
1) GET /setrole
2) POST /setrole
3) GET /setrole/info
Я правильно понял, что 1 - это для вывода формы, 2 - для обработки данных с формы, 3 - куда переадресовываем по итогу?
Мне как раз нужно что-то похожее на :
Цитата Сообщение от estic Посмотреть сообщение
Можно и на исходной форме отображать текущую роль, чтобы не делать модификацию
Сейчас форма изменения роли находится на той же страничке, что и вся информация о юзере.
А так же на этой страничке еще одна форма - управления активацией.

Все это должно доступно по GET /users/1
Обработчик управления ролью POST /users/1/rolecontrol
Обработчик управления активацией POST /users/1/activationcontrol
Переадресовывать по итогу на[quote="estic;14675416"]
GET /users/1
Можно было бы придумать какой-то индикатор в адресе использовать как селектор ошибок, но вместе с этим, в шаблон нужно еще объект пользователя передать. Вот тут скорее загвоздка с переадресацией.
Тут и сессии уже не совсем в тему..

Цитата Сообщение от estic Посмотреть сообщение
Достаточно новым состоянием радиокнопок показать, что действие завершилось успешно
Это как? В шаблоне выставлять статус checked в какой-то зависимости от результата(в какой)? Или о чем речь? Можно было бы этот вопос вообще обойти стороной, предлагая в шаблоне только возможные варианты изменения роли, чтобы даже возможности не было для ошибки повторного назначения той же самой роли(хотя и в других случаях повторная отправка присутствует. но визуально видно только в этом случае), но это еще куча условий. Да и интересно, как решить вопрос именно в этой ситуации.

Добавлено через 6 минут
Ну и остался открытый вопрос: Почему, если unset удаляет переменную из массива, проверка все равно не проходит?
0
1306 / 998 / 232
Регистрация: 01.10.2018
Сообщений: 3,884
23.06.2020, 18:10
Цитата Сообщение от СергейСереб Посмотреть сообщение
Я правильно понял, что 1 - это для вывода формы, 2 - для обработки данных с формы, 3 - куда переадресовываем по итогу?
Да.

Цитата Сообщение от СергейСереб Посмотреть сообщение
Это как? В шаблоне выставлять статус checked в какой-то зависимости от результата(в какой)?
Да, только лучше сказать "в зависимости от текущего значения". Как я понимаю, роль - это неотъемлемое свойство пользователя. Оно всегда должно иметь какое-то значение.

Цитата Сообщение от СергейСереб Посмотреть сообщение
чтобы даже возможности не было для ошибки повторного назначения той же самой роли
Зачем это вообще считать ошибкой?
0
165 / 150 / 58
Регистрация: 15.06.2013
Сообщений: 1,107
23.06.2020, 18:24
СергейСереб, я, конечно, могу ошибаться, но в документации сказано что, если unset используется в функции, то удаляется только локальная версия переменной.
0
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076
23.06.2020, 21:47  [ТС]
Цитата Сообщение от estic Посмотреть сообщение
Да, только лучше сказать "в зависимости от текущего значения". Как я понимаю, роль - это неотъемлемое свойство пользователя. Оно всегда должно иметь какое-то значение.
Я говорил о том, чтобы исключить вообще из шаблона роль, совпадающую с ролью пользователя. Сделал, но это естественно совершенно не меняет ситуацию с обновлением страницы.
Цитата Сообщение от estic Посмотреть сообщение
Зачем это вообще считать ошибкой?
А что это,если не ошибка? У пользователя уже назначена роль, а мы ему пытаемся такую же установить. Но опять таки, это не важно в контексте обсуждаемого вопроса.

Делал проверку на нажатие кнопки подтверждения - тоже не срабатывает. все равно повторно отправляется запрос по обновлению странички.

Можно просто напросто вообще убрать проверку на повторное назначение той же роли и соответственно выброс сообщения-ошибки об этом. Подобная ситуация не может быть воспроизведена пользователем(я ее уже исключил на уовне юзер-интерфейса). Или после изменения роли перекидывать на какую-то страничку с сообщением о переназначении. или вообще никаких сообщений не выдавать. а сделать посто переадресацию на страничку с информацией о юзере.
Но мне в любом случае интересно, как разрешить этот вопрос не отменяя эту проверку.

Цитата Сообщение от MadHatter Посмотреть сообщение
в документации сказано что, если unset используется в функции, то удаляется только локальная версия переменной.
Я же писал. что явно вижу, что переменная явно удаляется из массива. ЕЕ нет при обновлении странички.
Тут, я так понимаю, вопрос в том, что браузер кэширует запрос и ему все равно, что там удалили или не удалили.
0
165 / 150 / 58
Регистрация: 15.06.2013
Сообщений: 1,107
23.06.2020, 22:10
СергейСереб, Браузер к серверной части не имеет отношения. Если, конечно, вы повторно форму не отправляете. А вы пробовали выводить содержимое массива пост перед функцией иссет?
0
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076
23.06.2020, 23:08  [ТС]
Цитата Сообщение от MadHatter Посмотреть сообщение
Браузер к серверной части не имеет отношения.
Почему не имеет? Запрос то отправляется посредством браузера.
Цитата Сообщение от MadHatter Посмотреть сообщение
А вы пробовали выводить содержимое массива пост перед функцией иссет?
Как бы иначе я мог увидеть, что переменная удаляется из массива?

Сделал еще такой примитивный вариант: При выводе профиля пользователя стартую сессию, и в сессионную переменную записываю фиксированное значение. При отправке POST запроса сравниваю, при условии, что $_POST не пустой делаю поверку с этим же значением. После успешного выполнения POST запроса(на страничке я вижу об этом сообщение) присваиваю сессионной переменной новое рандомное значение. Вероятность совпадения с фиксированным значением крайне мала. После неудачи проверки делаю редирект на вывод профиля пользователя. (сообщение об успешном переназначении роли уже не выводится). По хорошему, обновление странички не должно убирать с экрана это сообщение.

Ну и в целом - какой-то конкретный костыль все это, как мне кажется....
0
 Аватар для Строитель
1084 / 746 / 364
Регистрация: 09.07.2018
Сообщений: 1,760
23.06.2020, 23:11
Цитата Сообщение от СергейСереб Посмотреть сообщение
Видел варианты - переадресовывать на ту же страничку. но я тогда не знаю, как правильно передавать сообщения в шаблон.
Сохранять их в сессии например.
0
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076
23.06.2020, 23:23  [ТС]
Цитата Сообщение от Строитель Посмотреть сообщение
Сохранять их в сессии например.
Объект куда девать? Тоже в сессию?
Цитата Сообщение от СергейСереб Посмотреть сообщение
вместе с этим, в шаблон нужно еще объект пользователя передать.
0
1306 / 998 / 232
Регистрация: 01.10.2018
Сообщений: 3,884
24.06.2020, 06:03
Цитата Сообщение от СергейСереб Посмотреть сообщение
Можно просто напросто вообще убрать проверку на повторное назначение той же роли и соответственно выброс сообщения-ошибки об этом.
Так я вам об этом и написал. Здесь единственная "выбрасываемая" ошибка, не считая 401, - это ошибка базы данных. Эту ошибку можно выдавать без перенаправления, выводя страницу ошибки 503, чтобы пользователь мог щелкнуть "Обновить" в интерфейсе клиента.

Мне не понятно, зачем нужен unset в данном контексте. Вы уже перешли на использование перенаправления? Я другими понятиями мыслить не могу в описанной ситуации.

Добавлено через 2 минуты
Цитата Сообщение от СергейСереб Посмотреть сообщение
в шаблон нужно еще объект пользователя передать
Видимо, не "перешли"
0
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076
24.06.2020, 09:04  [ТС]
Цитата Сообщение от estic Посмотреть сообщение
Вы уже перешли на использование перенаправления?
Я уже запутался в куче вариантов, и все они меня смущают.

В целом: Если делать без переадресации, нужно передавать и сообщение и объект пользователя, т.к. форма изменения роли находится на одной страничке с инфомацией о пользователе. Если делать переадресацию, то переадресацию нужно сделать на ту же страничку с информацией о пользователе и формой изменения роли.

С первым вариантом я уже все перепобовал - тупик, данные запроса без переадресации все равно при обновлении отправляются. Все проверки и условия на пустоту массива $_POST при этом игнорируются.

Со вторым вариантом, с переадресацией - да я ошибался, объект передавать будет не нужно. т.к. переадресация будет на страничку информации о пользователе с формой изменения роли(GET /users/1). Это отдельный обработчик и там объект пользователя получаю отдельно. Тогда вывод сообщений можно делать, как выше написали - через сессии. Нужно выводить и сообщение об успешной операции и о неуспешной. И на этой же страничке, на форме изменения роли. Вариант с модификацией адреса/передачей флага ошибки в адресе мне не очень нравится.

Цитата Сообщение от estic Посмотреть сообщение
зачем нужен unset в данном контексте
,
Если бы это работало в контексте обновления странички, было бы очень просто решить вопрос. А так, unset в данном контексте - получается бесполезен. Не имеет значения ткущее состояние $_POST, отправляются уже запомненные данные с последней отправки.
0
165 / 150 / 58
Регистрация: 15.06.2013
Сообщений: 1,107
24.06.2020, 09:04
Почему не имеет? Запрос то отправляется посредством браузера.
Отправляется, но браузер на сервере не может закешировать ваш пост запрос.
Как бы иначе я мог увидеть, что переменная удаляется из массива?
И что вы там увидели? Отсутствие ключа role?

Я не совсем понимаю, если вы все сделали с результатами отправки формы, то зачем вам дальше массив POST? Делайте редирект и забывайте про него.
0
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076
24.06.2020, 09:37  [ТС]
Цитата Сообщение от MadHatter Посмотреть сообщение

И что вы там увидели? Отсутствие ключа role?

.
Ну да.

Я не совсем понимаю, если вы все сделали с результатами отправки формы, то зачем вам дальше массив POST? Делайте редирект и забывайте про него.
Да мне этот массив и не нужен. Вопрос с редиректом- в контексте способа вывода сообщений о результате. Или через сессии или через параметр в адресе.

Добавлено через 5 минут
Цитата Сообщение от estic Посмотреть сообщение
Здесь единственная "выбрасываемая" ошибка, не считая 401, - это ошибка базы данных. Эту ошибку можно выдавать без перенаправления, выводя страницу ошибки 503, чтобы пользователь мог щелкнуть "Обновить" в интерфейсе клиента.
Почему "ошибки"? Я выбрасываю исключения. Учитываю неправильно переданный id пользователя, админ или не админ проводит операцию, соответствие текущей роли и назначаемой, была ли определена роль при подтверждении ее изменения, хотя как минимум последняя проверка- под сомнением, но как вариант- ситуация возможная. Или такие экзотические случаи не нужно обрабатывать?

Добавлено через 9 минут
И про архитектуру. Где правильнее/логичнее размещать обработчик изменения роли? В админконтроллере или в юзерконтроллере?
В админ удобнее, т.к. ко всем подобным обработчикам не нужно отдельно делать проверку на админ/не админ, а сделать это один раз для всех методов, подразумевающих доступ только админа, с другой стороны-манипуляции касаются пользователя, значит обработка должна быть в юзерконтроллере?
И на счет проверки доступа. Как лучше/правильно?: Делать проверки и на уровне представления(только админу показывать разрешенные элементы интерфейса) и на уровне кода, везде где предполагается доступ админа?
0
165 / 150 / 58
Регистрация: 15.06.2013
Сообщений: 1,107
24.06.2020, 10:02
Да мне этот массив и не нужен. Вопрос с редиректом- в контексте способа вывода сообщений о результате. Или через сессии или через параметр в адресе.
PHP
1
2
3
4
$_SESSION['msg'] = 'Ча ча ча';
header('location: ...');
echo($_SESSION['msg']);
unset($_SESSION['msg']);
1
1306 / 998 / 232
Регистрация: 01.10.2018
Сообщений: 3,884
24.06.2020, 12:34
Цитата Сообщение от СергейСереб Посмотреть сообщение
Если делать без переадресации
Для описанной ситуации альтернативы перенаправлению нет.

Цитата Сообщение от СергейСереб Посмотреть сообщение
Я выбрасываю исключения.
Это детали реализации. Я говорил про видимое поведение.

Цитата Сообщение от СергейСереб Посмотреть сообщение
Или такие экзотические случаи не нужно обрабатывать?
Смотрите: не админу бесполезные формы вовсе показывать не стоит, а прямые (POST-)запросы на изменение следует контролировать на уровне авторизации, т.е. при неавторизованных запросах (уровня админа) выдавать "без украшений" ошибку 403 или 401/требовать аутентификации админа, возможно, путем перенаправления.

Цитата Сообщение от СергейСереб Посмотреть сообщение
И про архитектуру.
Лично я всегда выделяю админку в отдельное приложение, так что с такими проблемами не сталкивался. Но если рассуждать по аналогии с авторизованным пользователем/гостем, то можно вынести контроль авторизации на уровень фронт-контроллера, т.е. "окрасить" маршруты или непосредственно "админконтроллеры" (если я правильно понял это слово) соответствующим образом, чтобы экшены без должного уровня доступа не вызывать (достаточно ограничиться вызовом тестового метода или даже проверкой его наличия).
1
39 / 9 / 10
Регистрация: 19.09.2016
Сообщений: 1,076
24.06.2020, 15:27  [ТС]
Цитата Сообщение от estic Посмотреть сообщение
я всегда выделяю админку в отдельное приложение
Я уже не первый раз слышу термин "приложение" в контексте веб-разработки. А как это выглядит технически? И почему/для чего отдельно?

Цитата Сообщение от estic Посмотреть сообщение
можно вынести контроль авторизации на уровень фронт-контроллера
У меня есть общий контроллер, от которого наследуются контроллер пользователя, контроллер админки(админконтроллер), контроллер комментариев, контроллер статей и т.д. В этом общем контроллере я получаю текущего пользователя. Могу тут же проверить. является ли юзер админом. Но смысла/удобства в этом наверное особого нет.

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

Добавлено через 51 минуту
Цитата Сообщение от MadHatter Посмотреть сообщение
$_SESSION['msg'] = 'Ча ча ча';
header('location: ...');
echo($_SESSION['msg']);
unset($_SESSION['msg']);
Как реализовать я понял. Выглядит это как -то коряво. В двух методах нужно стартовать сессию. В методе вывода информации о пользователе и формы - чтобы прочитать переменную и в методе обработки формы, чтобы установить переменную.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.06.2020, 15:27
Помогаю со студенческими работами здесь

Как избежать добавление в БД при обновлении страницы?
Доброго всем времени суток Проблема соответствует заголовку темы Код в катором происходит автоматическое добовление данных к БД...

Защита от повторной отправки POST-данных
браузер кэширует _POST. Если рефрешнуть то пост данные остануться, а значит сработает код еще раз. Надо после того, как 1 рах отправили...

Повторный POST при обновлении страницы
Возникла такая проблема: Есть форма, которая добавляет данные в mysql, после чего чуть ниже они(данные) и выводятся... Всё работает,...

Чтение данных с XML, как избежать повторной операции при следующей загрузке формы
Допустим есть такой код который Работает после загрузки второй формы. он считывает хмл файл в AutoCompleteMode. Так это довольно...

После повторной отправки Get-запроса и парсера выдается предыдущий результат
Есть IDHTTP,проходит процесс авторизации,далее идет get запрос, а с него идет парсер входящих сообщений,короче спарсил я...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru