PHP:Предотвратить случайную повторную обработку формы при нажатии кнопки «Назад»
-
22-07-2019 - |
Вопрос
Как лучше всего предотвратить повторную обработку формы, когда пользователь нажимает кнопку «Назад»?
я слежу за Опубликовать/перенаправить/получить шаблон, поэтому у меня нет проблем, если нажать F5, но кнопка «Назад» по-прежнему дает возможность повторно отправить форму.Если эта форма является страницей обработки кредитной карты, это плохо.
Этот вопрос несколько раз задавался здесь, но формулировки и ответы были низкого качества и не касались именно этой проблемы.
У меня есть form.php, который подчиняется самому себе.Если при отправке не было ошибок во входных данных, пользователь перенаправляется на form_thanks.php.Ответный удар (и «Отправить» или «Повторно отправить») один раз повторно отправляет form.php (ПЛОХО!), а затем возвращает их в form_thanks.php.
Пожалуйста, также включите решения, которые не предполагают использование сеансов, если это возможно.
Решение 2
Это следует сделать с помощью одноразового токена или nonce . Php / server должен включить этот токен в скрытое поле формы. Р>
В нем должен храниться список всех последних токенов, и каждый раз при отправке формы он должен проверять, находится ли токен в списке последних действительных токенов. Р>
Если его нет в списке, не перерабатывайте форму.
Если он есть в списке, обработайте форму и удалите токен из списка.
Токены могут обрабатываться в сеансах или просто в простой таблице базы данных без сеансов. Однако токены должны быть привязаны к пользователю.
Это также рекомендуемый способ избежать CSRF атак.
Другие советы
Я бы сделал это по-другому.Поместите скрытый ввод со случайной строкой в качестве значения, и когда он будет отправлен, сохраните эту случайную строку в сеансе.Настройте простую проверку, чтобы узнать, опубликовали ли они это уже и не принимают ли они ввод.
Просто мысли вслух здесь.А как насчет варианта post/redirect/get, где последнее получение на самом деле не является окончательным получением;) Скорее, оно, в свою очередь, всегда автоматически перенаправляется на действительно последнюю страницу, так что, если пользователь нажмет кнопку «Назад», он вернется прямо туда, откуда они пришли?
РЕДАКТИРОВАТЬ:
Хорошо, принимая во внимание комментарий ОП, вот еще одна идея.URL-адрес для отправки формы можно настроить так, чтобы он требовал параметра, подходящего только для одного использования.Этот токен будет сгенерирован (с использованием MD5 или чего-то подобного) до отправки формы и может быть сохранен в базе данных (в ответ на чье-то предложение вы запросили решение без использования сеансов).После обработки формы этот токен будет помечен в базе данных как уже использованный.Чтобы при возврате страницы с тем же токеном можно было предпринять шаги для предотвращения повторной отправки данных формы на серверную часть.
Поздний ответ, но можно вообще избежать обработки, используя решение на основе AJAX; не было бы проблемы с включением одноразового номера в эту схему обработки, но при использовании асинхронного запроса, который, в случае успеха, перенаправляет пользователя, запросы не повторяются при обновлении, нажатии назад или чем-либо, кроме нажатия кнопки. р>
Также легко реализовать механизм, который предотвращает двойное нажатие кнопки или ее «блокировку». если что-то произошло во время запроса путем встраивания в обработчик запроса (будь то высокий уровень с PrototypeJS или jQuery или низкий уровень с вашей управляемой функцией), механизмы для включения и отключения кнопки, когда запрос завершается и сначала срабатывает, соответственно. р>
Я обнаружил, что back вернет форму в состояние, в котором она находилась до перенаправления страницы, если это так, имеет скрытый ввод / переменную или что-то, начинающееся со значения, скажем true, затем после отправки формы, и если значение равно true, измените его на false и затем отправьте, иначе верните false
Попробуйте это:
<SCRIPT type="text/javascript">
window.history.forward();
</SCRIPT>