Контакти

Як заборонити повторне надсилання форми. Повторне надсилання даних форми під час оновлення сторінки. Запобігання повторному надсиланню форми за допомогою клієнтського редиректу

Свого часу спантеличив питанням - як захистити сторінки сайту від повторного відправлення даних форми під час оновлення сторінки (якщо перед цим було відправлення, звичайно).
Кожен веб-майстер та розробник напевно знає, що якщо на сайті ви натиснули кнопку «надіслати», заповнивши будь-яку форму, то після відправки, якщо спробувати оновити сторінку браузер видасть повідомлення з підтвердженням повторного відправлення.
У деяких моментах це неприпустимо. Наприклад, у разі елементарної форми зворотнього зв'язку. Коли користувач заповнив форму та відправив повідомлення, а потім з якоїсь йому однієї відомої причини оновив сторінку, лист пішов знову. Це може, звичайно, і не такий фатальний випадок, просто як приклад. Все набагато болючіше, наприклад, при надсиланні замовлення в інтернет-магазині.
Так ось поставив питанням пошуку вирішення цієї проблеми і зрозумів, що рішення тільки одне: використання перенаправлення після відправки форми header ('location: адреса'). Тобто. все просто – після відправки викликаємо перенапрямок (можна навіть на ту саму сторінку) та все! Оновлення сторінки буде чистим, без будь-яких заповнених POST-ів та GET-ів.

Все було б добре, але особисто я випробував із цим деякі проблеми. Вони полягають у наступному. Раніше, без використання переадресації, механізм відправлення даних на моїх сайтах працював наступним чином:
Користувач заповнює форму, тисне «надіслати», скрипт приймає відправлені дані, перевіряє їх на коректність (валідність, заповненість обов'язкових даних тощо) і видає відповідь – або операція пройшла успішно, або сталася помилка та список помилок (наприклад: помилка - поле «ім'я» не заповнене, а на сторінці надсилання вже в свою чергу видається відповідне повідомлення: надсилання успішне або не успішне.
Якщо відправка не успішна, форма залишається на екрані і поля її заповнені тими даними, які користувач ввів. Тобто. дані беруться зі змінної $_POST (якщо метод POST) і встають у відповідні поля (тобто повертаються з поста у свої поля, щоб наново їх не вводити). Адже всіх бісить коли ти заповнив форму, і не дай боже щось вказав неправильно і при спробі відправити тобі видається повідомлення, що щось заповнено неправильно, а форма оновлюється і знову порожня. І доводиться через одне неправильно заповнене поле наново її заповнювати.
Так ось, як уже сказав, у разі неуспішного заповнення форма залишається заповненою даними, взятими з $_POST, і користувач може виправити неправильні дані і знову відправити форму.
Все було гаразд і все працювало.
Але потім я зробив відправку з використанням переадресації і вийшло так, що після натискання кнопки "надіслати", у разі неуспішного заповнення, форма оновлювалася і в ній вже не могли залишитися заповнені поля, т.к. раніше вони автоматично заповнювалися з масиву $_POST, а тепер після того, як відбулася переадресація $_POST, підчистився начебто і не було ніякого відправлення.
Але на цей випадок знайшовся вихід. Використовувати сесії. Тобто. до виклику header передавати в змінні сесії дані з POST і потім після переадресації ними оперувати.
У результаті код значно ускладнився. Налагодження ускладнилося, т.к. взагалі важко визначити, що відбувається з функціями в той момент, коли трапляється переадресація. Якщо ти зробив якусь помилку в кодах (яка проявляється саме в момент відправлення), то вона навіть не висвітиться, тому відбудеться переадресація, і ти навіть не побачиш повідомлення про помилку.
Загалом мені після впровадження в свої коди header стало складніше працювати з моїми додатками. Розробка/доопрацювання/пошук помилок ускладнився. Але й відмовитись я від цього не можу.
І продовжую запитувати себе: а чи є інші, більш елегантні рішення?

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

Запобігання множинному відправленню з Javascript

Ймовірно, використання Javascript для запобігання повторному відправленню форми є самим легким способом. Коли користувач надсилає форму, можна відключити кнопку «Надіслати» і змінити її назву на щось зрозуміліше «Йде відправка, будь ласка, зачекайте…»

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

Другим (і останнім) кроком є ​​завдання двох Javascript команд у тезі

. Перша команда відключатиме кнопку «Надіслати» після відправлення форми, а друга змінюватиме текст кнопки, щоб дати користувачеві уявлення про те, що відбувається. Наступний код потрібно додати до теґу :

Тег form буде виглядати так:

onsubmit=»document.getElementById('myButton').disabled=true;

document.getElementById(‘myButton’).value=’Йде відправка, будь ласка, зачекайте..’;»

А після натискання кнопка перетворитись на таку

От і все. Цей прийом повинен працювати на більшості браузерів (IE 5+, FireFox, Opera, Chrome).

Запобігання множинному надсиланню за допомогою Cookies

Якщо ви хочете уникнути повторного надсилання форм протягом усієї сесії браузера (або довше), то можете розглянути можливість використання cookies. Наприклад, змінити сценарій редагування форми для передачі cookie браузеру після обробки форми, але до відправлення HTML заголовків. Розміщення даного коду після команди mail() має працювати здебільшого:

setcookie('FormSubmitted', '1');

Потім перевірте cookie перед обробкою. Якщо вони вже створені, користувач вже відправив форму в активній сесії браузера. Додайте наступний код на початку сценарію для обробки форми.


{
die('Ви може відправити форму лише один раз за сесію!');
}

От і все.

Ось як виглядатиме остаточна версія сценарію з використанням cookie для блокування повторного відправлення. Зверніть увагу, що частина коду була додана у верхній частині сценарію, а код для запису cookie знаходиться після функції mail().

/* Запобігання повторному відправленню */

if (isset($_COOKIE[‘FormSubmitted’]))
{
show_error('Ви можете надіслати форму лише один раз за сесію!');
}

/* Встановлення одержувача e-mail */

$myemail = « [email protected]»;

/* Перевірка введених на формі значень за допомогою функції check_input function */

$yourname = check_input($_POST['yourname'], "Введіть ваше ім'я");
$subject = check_input($_POST['subject'], "Тема повідомлення");
$email = check_input($_POST['email']);
$website = check_input($_POST['website']);
$likeit = check_input($_POST['likeit']);
$how_find = check_input($_POST[‘how’]);
$comments = check_input($_POST['comments'], «Ваші коментарі»);

/* Якщо введено неправильну адресу e-mail, показати повідомлення про помилку */
if (!preg_match(«/( [email protected]+.+)/», $email))
{
show_error(«Ви ввели неправильний e-mail»);
}

/* Якщо URL неправильна, встановлюємо порожнє значення для змінної $website */
if (!preg_match(«/^(https?://++.+)/i», $website))
{
$website=»;
}

/* Підготуємо e-mail повідомлення */

$message = Hello!
Ваші контактні дані надіслано:
Name: $yourname
E-mail: $email
URL: $website
Чи подобається веб-сайт? $likeit
Як ви знайшли веб-сайт? $how_find

Свого часу спантеличив питанням - як захистити сторінки сайту від повторного відправлення даних форми під час оновлення сторінки (якщо перед цим було відправлення, звичайно).
Кожен веб-майстер та розробник напевно знає, що якщо на сайті ви натиснули кнопку «надіслати», заповнивши будь-яку форму, то після відправки, якщо спробувати оновити сторінку браузер видасть повідомлення з підтвердженням повторного відправлення.
У деяких моментах це неприпустимо. Наприклад, у разі елементарної форми зворотного зв'язку. Коли користувач заповнив форму та відправив повідомлення, а потім з якоїсь йому однієї відомої причини оновив сторінку, лист пішов знову. Це може, звичайно, і не такий фатальний випадок, просто як приклад. Все набагато болючіше, наприклад, при надсиланні замовлення в інтернет-магазині.
Так ось поставив питанням пошуку вирішення цієї проблеми і зрозумів, що рішення тільки одне: використання перенаправлення після відправки форми header ('location: адреса'). Тобто. все просто – після відправки викликаємо перенапрямок (можна навіть на ту саму сторінку) та все! Оновлення сторінки буде чистим, без будь-яких заповнених POST-ів та GET-ів.

Все було б добре, але особисто я випробував із цим деякі проблеми. Вони полягають у наступному. Раніше, без використання переадресації, механізм відправлення даних на моїх сайтах працював наступним чином:
Користувач заповнює форму, тисне «надіслати», скрипт приймає відправлені дані, перевіряє їх на коректність (валідність, заповненість обов'язкових даних тощо) і видає відповідь – або операція пройшла успішно, або сталася помилка та список помилок (наприклад: помилка - поле «ім'я» не заповнене, а на сторінці надсилання вже в свою чергу видається відповідне повідомлення: надсилання успішне або не успішне.
Якщо відправка не успішна, форма залишається на екрані і поля її заповнені тими даними, які користувач ввів. Тобто. дані беруться зі змінної $_POST (якщо метод POST) і встають у відповідні поля (тобто повертаються з поста в свої поля, щоб наново їх не вводити). Адже всіх бісить коли ти заповнив форму, і не дай боже щось вказав неправильно і при спробі відправити тобі видається повідомлення, що щось заповнено неправильно, а форма оновлюється і знову порожня. І доводиться через одне неправильно заповнене поле наново її заповнювати.
Так ось, як уже сказав, у разі неуспішного заповнення форма залишається заповненою даними, взятими з $_POST, і користувач може виправити неправильні дані і знову відправити форму.
Все було гаразд і все працювало.
Але потім я зробив відправку з використанням переадресації і вийшло так, що після натискання кнопки "надіслати", у разі неуспішного заповнення, форма оновлювалася і в ній вже не могли залишитися заповнені поля, т.к. раніше вони автоматично заповнювалися з масиву $_POST, а тепер після того, як відбулася переадресація $_POST, підчистився начебто і не було ніякого відправлення.
Але на цей випадок знайшовся вихід. Використовувати сесії. Тобто. до виклику header передавати в змінні сесії дані з POST і потім після переадресації ними оперувати.
У результаті код значно ускладнився. Налагодження ускладнилося, т.к. взагалі важко визначити, що відбувається з функціями в той момент, коли трапляється переадресація. Якщо ти зробив якусь помилку в кодах (яка проявляється саме в момент відправлення), то вона навіть не висвітиться, тому відбудеться переадресація, і ти навіть не побачиш повідомлення про помилку.
Загалом мені після впровадження в свої коди header стало складніше працювати з моїми додатками. Розробка/доопрацювання/пошук помилок ускладнився. Але й відмовитись я від цього не можу.
І продовжую запитувати себе: а чи є інші, більш елегантні рішення?



Сподобалась стаття? Поділіться їй