Запретить повторную отправку формы php. Отмена повторной отправки формы. Предотвращение повторной отправки формы с помощью серверного редиректа

Запретить повторную отправку формы php. Отмена повторной отправки формы. Предотвращение повторной отправки формы с помощью серверного редиректа

В свое время озадачился вопросом - как защитить страницы сайта от повторной отправки данных формы во время обновления страницы (если перед этим была отправка, естественно).
Каждый веб-мастер и разработчик наверное знает, что если на сайте вы нажали кнопку «отправить», заполнив какую-либо форму, то после отправки, если попытаться обновить страницу браузер выдаст сообщение с подтверждением повторной отправки.
В некоторых моментах это бывает недопустимо. Например, в случае элементарной формы обратной связи. Когда пользователь заполнил форму и отправил сообщение, а потом по какой-то ему одному известной причине обновил страницу, письмо ушло снова. Это может, конечно, и не такой фатальный случай, просто как пример. Все гораздо болезненнее, например, при отправке заказа в интернет-магазине.
Так вот задался вопросом поиска решения этой проблемы и понял, что решение только одно: использование перенаправления после отправки формы header (‘location: адрес’). Т.е. все просто – после отправки вызываем перенаправление (можно даже на ту же страницу) и все! Обновление страницы будет чистым, без всяких заполненных POST-ов и GET-ов.

Все бы хорошо, но лично я испытал с этим некоторые проблемы. Они заключаются в следующем. Раньше, без использования переадресации механизм отправки данных на моих сайтах работал следующим образом:
Пользователь заполняет форму, жмет «отправить», скрипт принимает отправленные данные, проверяет их на корректность (валидность, заполненность обязательных данных и т.д.) и выдает ответ – либо операция прошла успешно, либо произошла ошибка и список ошибок (например: ошибка - поле «имя» не заполнено. А на странице отправки уже в свою очередь выдается соответствующее сообщение: отправка успешна или не успешна.
В случае если отправка не успешна, то форма остается на экране и поля ее заполнены теми данными, которые пользователь ввел. Т.е. данные берутся из переменной $_POST (если метод POST) и встают в соответствующие поля (т.е. возвращаются из поста в свои поля, чтобы заново их не вводить). Ведь всех же бесит когда ты заполнил форму, и не дай бог что-то указал неправильно и при попытке отправить тебе выдается сообщение, что что-то заполнено неправильно, а форма обновляется и снова пуста. И приходится из-за одного неправильно заполненного поля заново ее заполнять.
Так вот, как уже сказал, в случае неуспешного заполнения, форма остается заполненной данными, взятыми из $_POST, и пользователь может исправить неправильные данные и снова отправить форму.
Все было хорошо и все работало.
Но потом я сделал отправку с использованием переадресации и получилось так, что после нажатия кнопки «отправить», в случае неуспешного заполнения, форма обновлялась и в ней уже не могли остаться заполненные поля, т.к. раньше они автоматом заполнялись из массива $_POST, а теперь после того как произошла переадресация $_POST подчистился как будто и не было никакой отправки.
Но и на этот случай нашелся выход. Использовать сессии. Т.е. до вызова header передавать в переменные сессии данные из POST и уже потом после переадресации ими оперировать.
В итоге код усложнился значительно. Отладка усложнилась, т.к. вообще трудно определить что происходит с функциями в тот момент когда случается переадресация. Если ты сделал какую-то ошибку в кодах (которая проявляется именно в момент отправки), то она даже не высветится, т.к. произойдет переадресация и ты даже не увидишь сообщение об ошибке.
В общем, мне после внедрения в свои коды header стало сложнее работать с моими приложениями. Разработка/доработка/поиск ошибок усложнился. Но и отказаться я от этого не могу.
И продолжаю задаваться вопросом: а есть ли другие, более элегантные решения?

Допустим, мы делаем скрипт, который принимает данные из формы, переданные методом POST. Скрипт данные принял, обработал и выдал страницу с результатом. Но если пользователь вздумает обновить страницу в этот момент — он увидит сообщение такого плана:

Чтобы отобразить эту страницу, Firefox должен отправить информацию, которая повторит любое ранее произведённое действие (например, запрос на поиск или онлайн-покупка).

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

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

Можете отправить форму один раз, а потом нажать Ctrl+R и увидеть злополучное окно. Давайте от него избавляться.

Но сперва слово спонсору поста — сайту с полезным контентом для телефонов Samsung, который предлагает темы для samsung gt s5230 , обои и прочий стафф.

Предотвращение повторной отправки формы с помощью серверного редиректа

Чтобы предотвратить повторную отправку данных формы можно делать серверный редирект. Это делается путем посылки браузеру заголовка Location с нужным урл. Например, это должна быть страница с благодарностью за заполненную форму. Тогда мы напишем что-то в духе:

В этом случае сервер получит данные, обработает их и вместо показа результата отправит клиента на страницу, где этот результат будет показан.

Недостаток этого метода состоит в том, что пользователь может нажать кнопку "Назад" и вернуться на страницу с редиректом. Она снова швырнет его вперед и так пользователь с трудом сможет вернуться на две страницы назад, к форме, которую изначально заоплнял.

Предотвращение повторной отправки формы с помощью клиентского редиректа

Клиентский редирект называется клиентским потому что он происходит на стороне клиента. То есть в браузере. Клиентский редирект может происходить при помощи JavaScript и meta-тегов.

У JavaScript есть преимущество — он перезаписывает History браузера так, что даже если пользователь нажмет кнопку "Назад" браузера, он не вернется на страницу, которую отдал обработчик формы. То есть, окошко исчезнет капитально. Но JS у некоторых отключен.

У META-тегов, с другой стороны, есть преимущество в плане универсальности. Они редиректят всех и всегда.

Оптимально будет сочетать эти два способа. Как — описал Александр Шуркаев в заметке оптимальный редирект .

Используем его метод следующим образом.

Пробуем! Теперь, как видно, никакого окна не появляется. Что мы сделали? Мы проверили. Если данные пришли — мы выводим все необходимое для редиректа. В принципе, после этого уже можно даже делать exit, чтобы не грузить браузер лишними данными, которые все равно никто не увидит.

В свое время озадачился вопросом - как защитить страницы сайта от повторной отправки данных формы во время обновления страницы (если перед этим была отправка, естественно).
Каждый веб-мастер и разработчик наверное знает, что если на сайте вы нажали кнопку «отправить», заполнив какую-либо форму, то после отправки, если попытаться обновить страницу браузер выдаст сообщение с подтверждением повторной отправки.
В некоторых моментах это бывает недопустимо. Например, в случае элементарной формы обратной связи. Когда пользователь заполнил форму и отправил сообщение, а потом по какой-то ему одному известной причине обновил страницу, письмо ушло снова. Это может, конечно, и не такой фатальный случай, просто как пример. Все гораздо болезненнее, например, при отправке заказа в интернет-магазине.
Так вот задался вопросом поиска решения этой проблемы и понял, что решение только одно: использование перенаправления после отправки формы header (‘location: адрес’). Т.е. все просто – после отправки вызываем перенаправление (можно даже на ту же страницу) и все! Обновление страницы будет чистым, без всяких заполненных POST-ов и GET-ов.

Все бы хорошо, но лично я испытал с этим некоторые проблемы. Они заключаются в следующем. Раньше, без использования переадресации механизм отправки данных на моих сайтах работал следующим образом:
Пользователь заполняет форму, жмет «отправить», скрипт принимает отправленные данные, проверяет их на корректность (валидность, заполненность обязательных данных и т.д.) и выдает ответ – либо операция прошла успешно, либо произошла ошибка и список ошибок (например: ошибка - поле «имя» не заполнено. А на странице отправки уже в свою очередь выдается соответствующее сообщение: отправка успешна или не успешна.
В случае если отправка не успешна, то форма остается на экране и поля ее заполнены теми данными, которые пользователь ввел. Т.е. данные берутся из переменной $_POST (если метод POST) и встают в соответствующие поля (т.е. возвращаются из поста в свои поля, чтобы заново их не вводить). Ведь всех же бесит когда ты заполнил форму, и не дай бог что-то указал неправильно и при попытке отправить тебе выдается сообщение, что что-то заполнено неправильно, а форма обновляется и снова пуста. И приходится из-за одного неправильно заполненного поля заново ее заполнять.
Так вот, как уже сказал, в случае неуспешного заполнения, форма остается заполненной данными, взятыми из $_POST, и пользователь может исправить неправильные данные и снова отправить форму.
Все было хорошо и все работало.
Но потом я сделал отправку с использованием переадресации и получилось так, что после нажатия кнопки «отправить», в случае неуспешного заполнения, форма обновлялась и в ней уже не могли остаться заполненные поля, т.к. раньше они автоматом заполнялись из массива $_POST, а теперь после того как произошла переадресация $_POST подчистился как будто и не было никакой отправки.
Но и на этот случай нашелся выход. Использовать сессии. Т.е. до вызова header передавать в переменные сессии данные из POST и уже потом после переадресации ими оперировать.
В итоге код усложнился значительно. Отладка усложнилась, т.к. вообще трудно определить что происходит с функциями в тот момент когда случается переадресация. Если ты сделал какую-то ошибку в кодах (которая проявляется именно в момент отправки), то она даже не высветится, т.к. произойдет переадресация и ты даже не увидишь сообщение об ошибке.
В общем, мне после внедрения в свои коды header стало сложнее работать с моими приложениями. Разработка/доработка/поиск ошибок усложнился. Но и отказаться я от этого не могу.
И продолжаю задаваться вопросом: а есть ли другие, более элегантные решения?

Мне часто задают вопросы относительно отмены повторной отправки формы . Например, Вы сделали форму добавления комментария, добавили обработчик на эту же страницу. Затем при добавлении комментария он успешно добавляется, но стоит пользователю нажать F5 , как форма будет отправлена ещё раз . А F5 пользователь может легко нажать, если страница будет долго грузиться. В итоге, вместо 1-го комментария будет целых 2 , а то и больше. В этой статье я покажу, как этого можно избежать.

Для начала разберём более подробно проблему на примере этого кода:









Нажав на кнопку "Возвести в квадрат ", Вы увидите результат работы скрипта. Но стоит после этого пользователю нажать F5 , как скрипт снова будет выполняться. В данном случае, это не так критично, как с добавлением комментарием, однако, зачем нужна лишняя нагрузка на сервер?

Теперь поговорим о способах решения данной проблемы. Первый способ - выделить скрипт обработки в отдельный файл . Тогда в атрибуте action у тега form надо добавить путь к этому скрипту. А сам скрипт должен сохранять куда-нибудь результат своих действий, либо переменные пришедшие на скрипт, а после делать редирект обратно. В общем, смотрите код скрипта:

А код страницы с формой теперь будет выглядеть так:









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









Здесь обработка снова происходит в этом же файле, но ключевое отличие - это наличие редиректа на эту же страницу в конце . В результате, страница перегрузится после отправки формы и браузер при нажатии F5 не будет предлагать пользователю отправить форму ещё раз.

Подведу итог того, как отменить повторную отправку формы :

  • Либо делать обработку в отдельном файле , а затем оттуда делать редирект назад.
  • Либо делать обработку в том же файле, что и форма, но при этом после обработки делать редирект на ту же страницу .

Вот так это делается в простых скриптах. Да и, в сложных, в конечном счёте делается то же самое.

© 2024 iteleradio.ru - Твой компьютер