PRG в WEB приложениях
t.me/qa_chilloutКогда вы оформляете заказ в интернет-магазине или оставляете комментарий, за кулисами браузер и сервер обмениваются запросами. Чаще всего это, конечно же, отправляется на сервер в виде POST-запроса. Сервер обрабатывает полученные данные и, допустим, сохраняет ваш комментарий. Иногда из-за одного лишнего обновления страница может повторно что-то отправить — и это проблема. Комментарий может появиться дважды. Или, что хуже, деньги могут быть списаны повторно, если это был бы платёж.
Например:
- Пользователь заполняет форму и нажимает кнопку «Отправить».
- Форма отправляется методом POST — например,
POST /add-comment
. - Сервер сохраняет данные и возвращает HTML той же страницы с сообщением, например, "Комментарий добавлен".
Теперь если пользователь обновит страницу, браузер повторит последний запрос — а он был POST. То есть он повторно отправит форму. Комментарий снова добавится, или заказ снова оформится, и т.п.
Чтобы этого избежать, существует специальный приём — PRG.
Как это решает PRG
Чтобы избежать таких ситуаций, используют специальный подход —
POST → Redirect → GET, или просто PRG.
Вот как он работает:
- Пользователь нажимает кнопку — отправляется POST.
- Сервер сохраняет данные и вместо HTML даёт ответ с редиректом (
HTTP 302 Found
+ заголовокLocation: /success
). Браузер видит редирект и сам делает новый GET-запрос на/success
. - Сервер отдаёт уже готовую страницу с сообщением "Комментарий добавлен", без участия POST.
Теперь при обновлении страницы браузер обновит только GET-запрос к /success
. POST запрос повторно не выполняется, данные не дублируются.
Зачем нужен PRG:
- Предотвращает дублирование: если пользователь обновит страницу после POST, не произойдёт повторной отправки формы.
- Улучшает UX: можно безопасно делиться URL, копировать его, сохранять в закладках.
- Соответствует REST-принципам: изменения данных (выполняемые через метод POST) не должны происходить без явного намерения пользователя и не должны кешироваться браузером.
В чём польза
- Если вы обновите страницу — ничего не повторится. Комментарий не продублируется, платёж не уйдёт заново.
- Вы можете сохранить ссылку или отправить её другу — и не бояться, что у него тоже что-то «отправится».
- Это просто делает сайты более надёжными и удобными.
Что было бы без PRG
Пользователь после отправки формы видит успешный результат, но если он обновит страницу, то браузер предупредит: «Вы хотите повторно отправить данные формы?». Это может привести, например, к повторной оплате.
Кроме повторных оплат и ошибок, без PRG сайт может выглядеть «сломано»: пользователь не поймёт, отправились ли данные, или подумает, что всё зависло. Это ухудшает впечатление и может вызвать недоверие.
Всегда ли нужен PRG
На современных сайтах, построенных как SPA (Single Page Application) с помощью JavaScript (например, Gmail, Telegram Web, маркетплейсы), формы обрабатываются внутри страницы. Отправка данных и показ результата происходят без перезагрузки — а значит, повторная отправка при обновлении невозможна. В таких случаях PRG не обязателен.
Зачем тестировщику знать про PRG
QA важно знать про PRG, потому что этот паттерн напрямую влияет на поведение формы после отправки — без него могут возникать серьёзные баги.
Чек-лист для тестирования PRG:
- После отправки формы происходит редирект на другую страницу (а не остаётся на той же).
- При обновлении страницы не происходит повторной отправки данных (например, не появляется предупреждение браузера "Повторно отправить форму?").
- Данные не дублируются: комментарий, заказ или любая другая отправка не создаются повторно после обновления.
- В случае платежей — повторное списание невозможно при случайном обновлении после оплаты.
Обсудить статью, узнать больше можно в телеграм канале «Тестировщики нужны».