PHP:Предотвратить случайную повторную обработку формы при нажатии кнопки «Назад»

StackOverflow https://stackoverflow.com/questions/1646812

Вопрос

Как лучше всего предотвратить повторную обработку формы, когда пользователь нажимает кнопку «Назад»?

я слежу за Опубликовать/перенаправить/получить шаблон, поэтому у меня нет проблем, если нажать 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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top