Повторное выполнение SQL запроса

94
08 октября 2021, 13:30

Есть веб приложение на PHP + БД на MySQL. После выполнения какого-либо SQL запроса путем отправки данных через HTML форму, если обновить страницу, то SQL запрос выполняется снова, т.к. повторно отправляются данные в POST запросе. Это приводит к дублированию записей в БД.

Как можно этого избежать? Делать редирект через header() для каждой операции в браузере или есть другие решения?

Answer 1

Делайте редирект.

Веб-приложение, это приложение, которое работает через HTTP-протокол. Это значит, что с приложением пользователь взаимодействует с помощью HTTP-запросов. Каждый раз когда ваш пользователь хочет чего-то от вашего приложения, он отправляет запрос.

Например, пользователь заполняет форму и отправляет в приложение данные для сохранения -- делает POST запрос на написанный вами обработчик. А что делает ваш обработчик? Он сохраняет данные в бд и внезапно передаёт пользователю HTML-документ! Получается он делает сразу два дела: сохраняет и выдаёт документ. Это довольно паршивый дизайн, пердставьте функцию в php, которая обновляет ваше имя в базе и заодно выводит список любимых фильмов -- довольно неудобно.

Чтобы всем было удобно, ваш обработчик должен на запрос сохранения данных сказать "я всё сохранил, можете полюбоваться результатами там-то". Это редирект. Такой ответ не содержит html-документ для пользователя, а только указывает где его посмотреть. Браузер пользователя сделает новый запрос автоматически и не даст пользователю повторять запрос на сохранение нажатием на обновление.

Потом можете добавить отправку форм javascript'ом. Схема не поменяется. Один обработчик -- один результат.

Answer 2

Лучший вариант будет использовать csrf token и редирект после обработки формы.

Если в кратце про csrf, то это работает так: При запросе страницы где расположена ваша форма, вы генерируете рандомную большую строку и куда-нибудь её записываете. Например в кэш. В форме добавляете hidden поле с именем _csrf (на самом деле может быть любое) и значением - ваша строка.

При получении данных из формы вы проверяете, что для этого пользователя вы генерировали строку и что пришедшая строка совпадает. И только тогда выполняете запись в базу. Кэш, конечно, подчищаете. Теперь если придет ещё один такой же запрос, он просто не пройдет. Дополнительно вы получите защиту от csrf атак.

READ ALSO
Как сделать динамические мета-теги?

Как сделать динамические мета-теги?

Есть сайт в формате siteru, есть алиас домена krd

67
Как создать multiple insert в базу данных?

Как создать multiple insert в базу данных?

Есть многофайловая загрузка изображений, но в БД создается только одна строка!

86
Ошибка при передаче файла через AJAX

Ошибка при передаче файла через AJAX

Локалхост, передаю файл через AJAX-запросМассивы создаются и передаются в php файл, но про попытке разобрать всё на переменные получаю ошибку...

92
Bitrix — почему не выгружаются дополнительные свойства?

Bitrix — почему не выгружаются дополнительные свойства?

В программе 1с, создал дополнительные свойства, в которых указываю старую цену и скидкуВ bitrix в админке создал данные дополнительные свойства...

118