Отмена повторной отправки формы php. Повторная отправка данных формы при обновлении страницы. Предотвращение повторной отправки формы с помощью клиентского редиректа

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

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









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

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

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









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









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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Процесс отправки HTML формы может занять несколько секунд, прежде чем будет успешно передана форма и отображена страница ответа. Недостаточно терпеливые пользователи могут нажать кнопку «Отправить» несколько раз, что приведет к повторной отправке формы. Обычно это не представляет проблемы, но в некоторых случаях вы можете сделать, чтобы это не происходило.
Далее вы найдете два простых приема для предотвращения двойной отправки сообщений, вы можете использовать любой из этих или их комбинацию.

Предотвращение множественной отправки с Javascript

Вероятно, использование Javascript для предотвращения повторной отправки формы является самым легким способом. Когда пользователь отправляет форму, можно отключить кнопку «Отправить» и изменить её название на что-либо более понятное «Идет отправка, пожалуйста, подождите…»

Первым шагом является задание уникального идентификатора id , например id=»myButton»:

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

Тег form будет выглядеть следующим образом: