Когда человек заполняет форму и нажимает на кнопку «Отправить», может случиться всякое. Например, серверная часть может нормально отработать, а ответ клиенту не дойдет. Что мы (пользователи) тогда делаем? Ясное дело, нажимаем F5. Запрос отправляется еще разок с теми же данными. Серверная часть снова отрабатывает и на это раз возвращает ответ — страницу с продублированным комментарием (новостью, товаром, постом на форуме). Сталкивались с этим явлением?
Как же распространенную проблему решить? У меня четыре варианта.
1. Перед записью в базу данных можно делать запрос на предмет наличия в таблице отправляемого текста. Лишний не очень быстрый запрос. Нужно писать код проверки.
2. Можно установить для пользователя ограничение по времени, скажем, одна запись в базу в течение 30 секунд. Всё равно нужно писать код.
3. Есть вариант с редиректом: сервер возвращает легкую страничку, с которой пользователь мгновенно куда-нибудь перенаправляется. Недостаток — если легкая страничка не дойдет, то дублирования не избежать.
4. Делаем UNIQUE-индекс в таблице. Можно по нескольким полям. Смотрим, если MySQL возвращает код ошибки 1062, значит, данные уже записались. На данный момент это мой выбор. Я правда не уверен, что использую этот тип индекса по назначению, но каких-то недостатков не замечал.
Кстати, по неизвестным причинам большинство популярных CMS не решают проблему повторной записи данных. Wordpress получает плюсик.
Утреннее дополнение
Вариант с UNIQUE, как оказалось, отягощается парой недостатков.
Дмитрий Сергеев, 21 год. Разрабатываю сайты на Drupal и CakePHP.
Владимир Михайличенко, 14.06.2007 01:06
Есть еще пятый способ.
С помощью Ajax очень просто и удобно решать эту проблему. Заполнил поля, нажал на кнопку, если случился глюк и клиент ответа не получил, то спокойно жмет F5 и видит что его сообщение не добавилось и преспокойно повторяет опрерацию.
Серверная часть все равно два раза с темиже данными не вызывается.