Защита от повторно изпращане на форма

madmax3

Member
Здравейте

Предполагам, че и други като мен са имали проблеми когато една форма, умишлено или неумишлено, се изпраща повече от веднъж.

Ето какво измислих:

демо: http://geobg.info/web/users/reload.php

И самия код:

<?php

session_start();

?>
<html>
<head>
<title>Prevent dowble submit</title>
</head>
<body>
<div style="width: 900; margin: 5px auto; text-align: center; padding: 50px 0;">
<?php

if (count($_POST))
{
if ($_SESSION['submitFlag'] != 1)
{
echo "<div style='color:green;'>Submit form successfully</div>";

$_SESSION['submitFlag'] = 1;
}
else
{
echo "<div style='color:red;'>Form already sent</div>";
}

echo "<hr/><a href='?'>Reset form</a><br/><br/>";
}
else
{
$_SESSION['submitFlag'] = 0;
}
?>
<form name="test" method="post">
<input type="text" name="userText" value="" />
<input type="submit" name="send" value="Send data" />
</form>
</div>
</body>
</html>

Ще ви бъда благодарен да споделите какво мислите за това както и как се справяте с този проблем (без капча и допълнителни действия от потребителя).
 
От: Защита от повторно изпращане на форма

Има много варианти да ползваш AJAX,или просто след събмит да рефрешнеш страницата
 
От: Защита от повторно изпращане на форма

Редирект след изпращане е друг вариант. Друг вариант е с hidden променлива, която е уникална всеки път ( точно като капчата, само че без да попълва капча ) или пък формата да е примерно action='script.php?submited=1', или пък уникалната променлива да е в action-а

Според зависи за какво иде реч, примерно не е проблем да рефрешва и да изпраща повторно информацията ако правиш проверка, дали не си записал тези данни от формата и ти трябват уникални ( примерно за абонамент някакъв, където си въвежда име / мейл, тези данни ти трябват веднъж, така че веднъж като ги запишеш му връщаш грешка, че вече си ги имаш и не ги искаш наново, освен ако не иска по няколко пъти да получава един и същ мейл, примерно )

Хипотетична ситуация, отворил съм две различни форми в твоя сайт, като и двете използват горния метод. Попълвам едната изпращам, слага ми 'submitFlag' = 1, попълвам втората във втория таб изпращам и ми се кара, че вече е съм го изпратил ...

П.С. В 99.99% от случаите най-вероятно метода ти ще свърши работа : )
 
От: Защита от повторно изпращане на форма

Кода който си дал ще работи на всеки, който е разрешил на браузъра си да приема кукита от твоя домейн.
Другият проблем, е че няма как да ползвам формата втори път ако се наложи - ще трябва да изтрия кукито за сесията за да получа след това чисто "досие" :).

Пращай данните към друг скрипт, който ги обработва, след което пренасочва към правилното място (коментари в новини, форма за контакти и т.н.).
 
От: Защита от повторно изпращане на форма

Май не си много наясно с PHP, ама както и да е само ще ти кажа, че между:

PHP:
$_SESSION['submitFlag'] ;

И

PHP:
$_COOKIE['submitFlag'] ;

Иначе @uphero е прав, аз бих предпочел jq + ajax, но всеки си решава сам за себе си.


Кода който си дал ще работи на всеки, който е разрешил на браузъра си да приема кукита от твоя домейн.
Другият проблем, е че няма как да ползвам формата втори път ако се наложи - ще трябва да изтрия кукито за сесията за да получа след това чисто "досие" :).

Пращай данните към друг скрипт, който ги обработва, след което пренасочва към правилното място (коментари в новини, форма за контакти и т.н.).


Към автора, с тоя нациклен и начупен код още ли така ви учат, че е по-добре да се пише?

После не се чудете защо WP, и другите готови бъкии тварят машините като за световно, да не говорим, че човек като види кода и може да се хване за главата.

Тука има тука, нема. Така учат в училище да се програмира на PHP.

За да покажеш HTML в пхп си има няколко функции, и едно отваряне и затваряне на самото php товари много повече от колкото едно:

PHP:
echo"Аз съм пич ;)";
 
От: Защита от повторно изпращане на форма

@uni-web щом ще го караме на изясняване нека започнем от началото:
Идентификатора към сесията по подразбиране се пази в cookie с име PHPSESSID. И тъй като SESSION масива в php-то са данните записани за определена сесия (файл на сървъра обвръзан с този идентификатор) то след като презаредиш страницата вече си с нов идентификатор и няма как да достъпиш данните от друга сесия.
 
От: Защита от повторно изпращане на форма

Да, и най-просто да удари една семпла проверка за == данни в базата данни, ако я има - нищо, ако я няма - записва.
 
От: Защита от повторно изпращане на форма

След като знаеш къде се пази сесията, защо казваш, че като си изключи кукитата на браузъра нямало да работи кода?

Това ми беше идеята с корекцията към теб! ;)

@uni-web щом ще го караме на изясняване нека започнем от началото:
Идентификатора към сесията по подразбиране се пази в cookie с име PHPSESSID. И тъй като SESSION масива в php-то са данните записани за определена сесия (файл на сървъра обвръзан с този идентификатор) то след като презаредиш страницата вече си с нов идентификатор и няма как да достъпиш данните от друга сесия.
 
От: Защита от повторно изпращане на форма

Така излишно пък ще се ползва и MYSQL сървъра, което при суперите вече и на споделения хостинг го броят за процесорно време, не е като едно време. :)

Да, и най-просто да удари една семпла проверка за == данни в базата данни, ако я има - нищо, ако я няма - записва.
 
От: Защита от повторно изпращане на форма

@uni-web не знам как по-ясно да ти обясня, че без cookie няма как да достъпиш до данните от сесията. Просто виж линка, който съм дал за повече подробности.
Ако се чудиш къде има проблем със кукитата ведната ти казвам - част от мобилните устройства. Първите ipad-ове и част от андроидските(не помня коя версия бяха).
Разбира се може да предаваш сесийното ID по GET и този проблем изчезва, но пък не изглежда user friendly :).

@wessly ако записваш коментари от форма е вариант, макар че за целта има уникални ключве и няма нужда от сравнение.
 
От: Защита от повторно изпращане на форма

if($_POST['post_form'] == 1){//пратили сме фомата, post_form ни е скрито поле във формата, което е със стойност 1
...обработваме формата....

header('location:'.$_SERVER['HTTP_REFERER']);
}

Това е решение за да не се препраща при рефреш на страницата.
 
От: Защита от повторно изпращане на форма

@mgrozdanov решение, но половинчато ако мога така да се изразя.
The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.
Да не говорим че с така написано пренасочване всичко след "header('location:'.$_SERVER['HTTP_REFERER']); }" ще се изпълни и чак тогава ще бъде пренасочен потребителя. Слагай по един exit; след такова пренасочване да избегнеш този проблем.
 
От: Защита от повторно изпращане на форма

Аз само да попитам Митрев ,аджеба кой и по какъв повод си изключва бисквитките(изключвам хората които знаят за тях - 6%)?
 
От: Защита от повторно изпращане на форма

@uphero както написах преди няколко поста - някой мобилни устройства не приемат бисквитки.
 
  • Like
Реакции: Sky
От: Защита от повторно изпращане на форма

Mitrev, за мен лично е безмислено да се съобразявам с някакви нечувани браузъри, "някои" мобилни устройства, и хора, които си изключват cookies. За 'exit' съм съгласен, но пък ако влезне някой от твоите хора със страните браузъри ще остане на бял екран. За една проста форма не виждам смисъл да се правят излишни неща. header('location:'.$_SERVER['HTTP_REFERER']); винаги може да си го смениш с точен адрес от сайта и да ти е мирна главата header('location: submit.php');
 
От: Защита от повторно изпращане на форма

@mgrozdanov за теб може да е безмислено, но да губиш пари заради някакво парче код е просто безумие - поне за мен де.
Имам наблюдения над един голф проект - в него 80% от продажбите за последните 3 месеца са направени точно през такива мобилни у-ва(ipad и някакъв си андроид таблети, но не си казва каква марка е). Ако не бяхме видяли проблема на време и да го решим нямаше да има пари, защото хората просто нямаше да могат да купят каквото и да било.

Нечуван ли е Firefox според теб? Firefox/15.0 е точно версията, която не даваше реферер.
 
От: Защита от повторно изпращане на форма

Не си уточнил за какво ще ползваш тази форма, но аз бих го направил така:

При успешен събмит скрипта изпраща юсер-а на друга страница, или криеш формата и остава на текущата със текст "Благодаря ви!"(например), по този начин той няма как да се обърка да направи повторен събмит, но в същото време не го и спираш да влезе пак в тази форма и да пусне други данни( например имаш форма за контакти и потребителя иска да ти пише 2 пъти подред ).

Отделно ако искаш да предотвратиш дубъл клик на събмит бутона, го правиш със javascript -> disable на бутона при пъривия събмит и пак горното решение.
 
От: Защита от повторно изпращане на форма

Аз писах ама кой да чете...
AJAX е решението
 
От: Защита от повторно изпращане на форма

ajax чак няма нужда, еднин прост javascript метод само
 
От: Защита от повторно изпращане на форма

AJAX е JS, така че за какво спорите?
 

Горе