Як заборонити повторне надсилання форми. Повторне надсилання даних форми під час оновлення сторінки. Запобігання повторному надсиланню форми за допомогою клієнтського редиректу
Свого часу спантеличив питанням - як захистити сторінки сайту від повторного відправлення даних форми під час оновлення сторінки (якщо перед цим було відправлення, звичайно).
Кожен веб-майстер та розробник напевно знає, що якщо на сайті ви натиснули кнопку «надіслати», заповнивши будь-яку форму, то після відправки, якщо спробувати оновити сторінку браузер видасть повідомлення з підтвердженням повторного відправлення.
У деяких моментах це неприпустимо. Наприклад, у разі елементарної форми зворотнього зв'язку. Коли користувач заповнив форму та відправив повідомлення, а потім з якоїсь йому однієї відомої причини оновив сторінку, лист пішов знову. Це може, звичайно, і не такий фатальний випадок, просто як приклад. Все набагато болючіше, наприклад, при надсиланні замовлення в інтернет-магазині.
Так ось поставив питанням пошуку вирішення цієї проблеми і зрозумів, що рішення тільки одне: використання перенаправлення після відправки форми header ('location: адреса'). Тобто. все просто – після відправки викликаємо перенапрямок (можна навіть на ту саму сторінку) та все! Оновлення сторінки буде чистим, без будь-яких заповнених POST-ів та GET-ів.
Все було б добре, але особисто я випробував із цим деякі проблеми. Вони полягають у наступному. Раніше, без використання переадресації, механізм відправлення даних на моїх сайтах працював наступним чином:
Користувач заповнює форму, тисне «надіслати», скрипт приймає відправлені дані, перевіряє їх на коректність (валідність, заповненість обов'язкових даних тощо) і видає відповідь – або операція пройшла успішно, або сталася помилка та список помилок (наприклад: помилка - поле «ім'я» не заповнене, а на сторінці надсилання вже в свою чергу видається відповідне повідомлення: надсилання успішне або не успішне.
Якщо відправка не успішна, форма залишається на екрані і поля її заповнені тими даними, які користувач ввів. Тобто. дані беруться зі змінної $_POST (якщо метод POST) і встають у відповідні поля (тобто повертаються з поста у свої поля, щоб наново їх не вводити). Адже всіх бісить коли ти заповнив форму, і не дай боже щось вказав неправильно і при спробі відправити тобі видається повідомлення, що щось заповнено неправильно, а форма оновлюється і знову порожня. І доводиться через одне неправильно заповнене поле наново її заповнювати.
Так ось, як уже сказав, у разі неуспішного заповнення форма залишається заповненою даними, взятими з $_POST, і користувач може виправити неправильні дані і знову відправити форму.
Все було гаразд і все працювало.
Але потім я зробив відправку з використанням переадресації і вийшло так, що після натискання кнопки "надіслати", у разі неуспішного заповнення, форма оновлювалася і в ній вже не могли залишитися заповнені поля, т.к. раніше вони автоматично заповнювалися з масиву $_POST, а тепер після того, як відбулася переадресація $_POST, підчистився начебто і не було ніякого відправлення.
Але на цей випадок знайшовся вихід. Використовувати сесії. Тобто. до виклику header передавати в змінні сесії дані з POST і потім після переадресації ними оперувати.
У результаті код значно ускладнився. Налагодження ускладнилося, т.к. взагалі важко визначити, що відбувається з функціями в той момент, коли трапляється переадресація. Якщо ти зробив якусь помилку в кодах (яка проявляється саме в момент відправлення), то вона навіть не висвітиться, тому відбудеться переадресація, і ти навіть не побачиш повідомлення про помилку.
Загалом мені після впровадження в свої коди header стало складніше працювати з моїми додатками. Розробка/доопрацювання/пошук помилок ускладнився. Але й відмовитись я від цього не можу.
І продовжую запитувати себе: а чи є інші, більш елегантні рішення?
Процес відправлення HTML формиможе зайняти кілька секунд, перш ніж буде успішно передана форма та відображено сторінку відповіді. Недостатньо терплячі користувачі можуть натиснути кнопку «Надіслати» кілька разів, що призведе до повторного відправлення форми. Зазвичай це не є проблемою, але в деяких випадках ви можете зробити, щоб це не відбувалося.
Далі ви знайдете два простих прийоми для запобігання подвійному надсилання повідомлень, ви можете використовувати будь-який з цих або їх комбінацію.
Запобігання множинному відправленню з Javascript
Ймовірно, використання Javascript для запобігання повторному відправленню форми є самим легким способом. Коли користувач надсилає форму, можна відключити кнопку «Надіслати» і змінити її назву на щось зрозуміліше «Йде відправка, будь ласка, зачекайте…»
Першим кроком є завдання унікального ідентифікатора idнаприклад id=»myButton»:
Другим (і останнім) кроком є завдання двох Javascript команд у тезі