Проверка и отправка формы (jqery+php)
Здравствуйте!
Целый день пыхтел, гуглел, совсем загудел :) Прошу помощи :help: Есть форма комментариев, без родной капчи, пытаюсь ее прикрутить.У Удивительно, но алгоритм такой: каптча дает "ок" - форма должна отправиться, каптча дает нет, должна появится ошибка. Вот форма <form method="post" name="uploader" enctype="multipart/form-data" id="commt"> <inline> <div class="textarea"> <inline class="second"> <input type="text" name="sended_name" required placeholder="Имя" value="<?echo$REAL_NAME?>" <?echo$disabled_name?> > <label><img src="<?echo$dir_blocks_http?>email.png" alt="email" class="email"></label> <input type="email" name="sended_email" required placeholder="Email" value="<?echo$REAL_EMAIL?>" <?echo$disabled_email?> > <input type="hidden" name="img_hidden" required placeholder="Email" value=""> <input type="submit" id="submit" name="send_comments" value="Отправить"/> <span><?=$_SESSION['msg']?></span> <?php unset ($_SESSION['msg']);?> </inline> <p>Сколько <?=$color?> яблок?<br /><?="$first_l$second_l"?> <br /> Ваш ответ: <input type="text" id="result" name="result" value="" style="width:17px; font-weight:bold;margin-top: 10px;" /><br /></p> </div> </inline> <script> $(document).ready(function(){ $("#commt").submit(function(){return false;}); $("#send_comments").on("click",function(){ var msg=$("#result").val(); // если обе проверки пройдены // сначала мы скрываем кнопку отправки $("#send_comments").replaceWith("<em>отправка...</em>"); $.ajax({ type:'POST', var resok = $('div.hidden').data('lat'); resok:$("#commt").serialize(), success:function(resok){ if(resok=="1"){ $("#commt").fadeOut("fast", function(){ $(this).before("<p><strong>Ваше сообщение отправлено</strong></p>"); setTimeout("$.fancybox.close()",1000); }); } } }); }); }); </script> <?php $first = rand(1, 5); //получаем случайное значение $second = rand(1, 5); if ($first == $second) {//убираем возможность одинаковости первого и второго числа и исключаем тем самым нулевой результат $first = rand(1, 3); $second = rand(4, 5); } function mirror ($name, $name_l) //привязываем к выводимой в браузер ($first_l и $second_l) переменной текстовое значение в соответствии с используемой при вычислении { $g = "1";//картинка яблока $r = "0"; switch ($name) { case 1: $name_l = "$g"; break; case 2: $name_l = "$r$g"; break; case 3: $name_l = "$r$g$r"; break; case 4: $name_l = "$r$g$r$g"; break; case 5: $name_l = "$r$g$r$g$r"; break; } return $name_l; } $first_l = mirror ($first, $first_l); //инициализируем переменную $second_l = mirror ($second, $second_l); // привязываем количество цвета к значению $first и $second function mirrorColor ($numvar){ switch ($numvar) { case 1: $green = 1; $red = 0; break; case 2: $green = 1; $red = 1; break; case 3: $green = 1; $red = 2; break; case 4: $green = 2; $red = 2; break; case 5: $green = 2; $red = 3; break; } return array ($green, $red); } $f_color = mirrorColor ($first);// инициализируем массив $s_color = mirrorColor ($second); $gr_word = "<span style=color:green;font-weight:bolder>зеленых</span>"; $red_word = "<span style=color:red;font-weight:bolder>красных</span>"; $t = time(); //инициализируем переменную для смены операций временем в секундах на момент запроса if ($t & 1) //меняем операцию в соответствии с четностью переменной { $_SESSION['res'] = $f_color['0'] + $s_color['0']; //заносим результат в сессионную переменную $color = "$gr_word";//выводимое в браузер название цвета } else { $_SESSION['res'] = $f_color['1'] + $s_color['1']; $color = "$red_word"; } if (isset($_POST['result'])) { //если это был ответ if (trim(strip_tags($_POST['result'])) == $_SESSION['res']) { //убираем, на всяки случай, теги и пробелы с обоих сторон и сравниваем результаты $_SESSION['msg'] = " Верно<br />"; $Lat = ["1"]; } else { $_SESSION['msg'] = " Ошибка<br />"; $Lat = ["0"]; } if (empty($_POST['result'])) { $_SESSION['msg'] = " Нужно ввести ответ...<br />"; $Lat = ["0"]; } } ?> |
Цитата:
$first = rand(1, 5); //получаем случайное значение $second = rand(1, 5); .... |
Цитата:
|
Если один файл, то это не верно, структура файла должна быть такой:
1) старт/продолжение сессии 2) проверка наличия запроса клиента и если он произошел, то проверяем условия каптчи и другие поля, результат проверки отдаем клиенту, после чего обязательное прекращение работы скрипта 3) подготовка параметров каптчи 4) вывод html страницы клиенту $_SESSION['msg'] = " Верно<br />"; - это, как и <span><?=$_SESSION['msg']?></span><?php unset ($_SESSION['msg']);?> лишнее. Данный элемент должен выводить текст по умолчанию, а ответы на проверку совсем не нужно хранить в сессии, у вас асинхронный запрос. Поэтому проверили запрос, выдали перечень всех ошибок клиенту, если они есть, или дальнейшее действие, если все Ок. "убираем, на всяки случай, теги и пробелы с обоих сторон и сравниваем результаты" - это бесполезность, нужно так - https://www.php.net/manual/ru/book.filter.php. $("#commt").submit(function(){return false;}); - не так, а так: $("#commt").submit(function(e){ e.prevetDefault(); //какие-то действия //ajax запрос и обработка ответа сервера }); А этот обработчик $("#send_comments").on("click",function() ... удалить. |
1. Старт сессии объявляется выше этого файла, здесь продолжение.
(капча работает, отдает верно/неверно по условию) 2. В моем случае нужна проверка только капчи, как это реализовать правильно? 3. Капча (php скрипт), и так работает над html формой 4. А что не так с фильтром? он же очищает все теги. Я так понимаю, можно использовать, number_int, но что-то не нашел более-менее понятных для меня примеров. |
Цитата:
<? session_start(); //каптча $_SESSION['check'] = rand(1, 9); //обработка запроса if(isset($_POST['test'])) exit('input: '.$_POST['test'].', check: '.$_SESSION['check']); ?> <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script type="text/javascript"> $(function() { $('input').keyup(function() { var f = this; $.post(location, {test: f.value}, function(d) { alert(d); f.value = '' }) }) }); </script> </head> <body> <input /> </body> </html> и пока в нем строки 4 и 6 не поменять местами ввод будет равен каптче только если повезет. Почему, думаю, пояснять не надо. Цитата:
Если имеется ввиду, что сперва нужно проверить ввод каптчи, и только затем разрешить отправление формы, то нужно изменить логику скриптов сервера и клиента. |
Совсем запутался.
Насчет проверки, а что еще нужно проверять? Верно ли я понял что нужно использовать number_int? мы же очистим все кроме цифр, разве нет? p.s. я ж не профи, очень многого не знаю :) Кажется, я не правильно изначальную информацию дал Вот полный файл: Код:
<?php И да, капча как бы работает. Цель вроде простая, средствами jqery сделать проверку на капчу, и в случае успеха отправить форму. Но вы говорите что еще и остальные поля надо проверить, но что и как... |
Цитата:
Вот код что я давал: <? session_start(); //каптча $_SESSION['check'] = rand(1, 9); //обработка запроса if(isset($_POST['test'])) exit('input: '.$_POST['test'].', check: '.$_SESSION['check']); ?> Во-первых, и что понятно, он обязательно должен быть до вывода в браузер. Во-вторых, если сначала готовится каптча, сохраняется в сессии, а следующей операцией, это проверка равенства ее с вводом, то при каждом запросе клиента значение каптчи будет перезаписываться еще до проверки. Такая же неверная логика в коде и у вас, как может работать сначала: $_SESSION['res'] = $f_color['1'] + $s_color['1']; а затем: if (trim(strip_tags($_POST['result'])) == $_SESSION['res']) ? Верно, это: <? session_start(); //обработка запроса, с обязательным прекращением работы скрипта - exit //иначе клиенту будет вывален код всей страницы if(isset($_POST['test'])) exit('input: '.$_POST['test'].', check: '.$_SESSION['check']); //каптча $_SESSION['check'] = rand(1, 9); ?> Либо, каптча готовится отдельным скриптом, к которому клиент обращается при загрузке страницы. Цитата:
Для проверки каптчи не нужно никакого фильтра, достаточно проверки ввода с сохраненным на сервере. А вот для всего остального требуется фильтрация. |
Цитата:
Т.е. я изначально пошел не верным путем решив все засунуть в один файл? Вообще вот та самая капча которую хочу - http://coderhs.com/archive/captcha_math_text (последнее). |
Ну так разницу видите? Там каптча, это отдельный от обработчика формы файл, а вы скрестили все в одно, но порядок скриптов при этом неверный, а каков правильный должен быть порядок я уже писал выше.
|
Ошибку понял. Но как сделать проверку посредством jqery? как обратиться к файлу с ответом от капчи и при верном условии, форму отправить?
|
Делать отдельный запрос для проверки каптчи, при этом не обязательно код каптчи должен быть отдельным файлом, ибо имя у поля каптчи, а это ключ на сервере, свое, значит даже расположив в одном файле прием запроса каптчи и запрос формы, по имени ключа в запросе можно определить что интересует клиента.
Нужно только выполнить два обязательных условия: 1) Обработка асинхронных запросов клиента должна быть в самом начале файле, а при работе с сессией после ее продолжения. 2) Код обработки запроса должен заканчиваться завершением работы скрипта функцией exit. Ответ клиенту при этом может быть аргументом данной функции, если ответ это строка, которая будет выведена в браузер. Если этой функции передать число, то это будет принято как код завершения и вывода в браузер не будет. |
Что касается логики, то решений может быть туева туча. Вот два примера и оба это один скрипт, можете их запустить на локальном сервере под любым именем.
1) Согласно условиям ранее оговоренным: <? session_start(); //обработка запросов if($_POST) { switch($k = key($_POST)) { case 'check': $out = $_SESSION['check']==(int)$_POST[$k] ? '' : 'Завтра в школу с родителями!'; break; case 'text': $out = 'Ok'; } exit($out); } //каптча $a = ['+','-','*']; shuffle($a); $check = rand(1, 10) . $a[0] . rand(1, 10); eval('$_SESSION[check]='.$check.';'); ?> <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script type="text/javascript"> $(function() { $('button').click(function() { $.post(location, {check: $(this).prev().val()}, function(d) { if(!d) $('form').submit(); else alert(d); }) }); $('form').submit(function(e) { e.preventDefault(); $.post(location, $(this).serialize(), function(d) { alert(d) }) }); }); </script> </head> <body> <form> <input name="text" value="Text" /> </form> <span>Сколько: <?=$check?>=?</span> <input name="check" /> <button>Проверка</button> </body> </html> Но при таком решении затруднительно обновлять каптчу при ошибках и после приема формы. Но достаточно генерацию каптчи сделать функцией, которую можно размещать хоть до обработки запросов, хоть после, эту задачу легко решить. 2) Генерация каптчи функцией и обмен с сервером в формате JSON. <? session_start(); //каптча function check() { $a = ['+','-','*']; shuffle($a); $check = rand(1, 10) . $a[0] . rand(1, 10); eval('$_SESSION[check]='.$check.';'); return $check; } //обработка запросов if($_POST) { switch($k = key($_POST)) { case 'check': $out = $_SESSION['check']==(int)$_POST[$k] ? '' : ['err'=>1, 'exp'=>check(), 'msg'=>'Двойка! Завтра в школу с родителями!']; break; case 'text': $out = ['exp'=>check(), 'msg'=>'Ok!']; } exit(json_encode($out)); } ?> <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script type="text/javascript"> $(function() { $('button').click(function() { var f = $(this).prev(); $.post(location, {check: f.val()}, function(d) { if(!d.err) $('form').submit(); else { $('span').text(d.exp); f.val(''); alert(d.msg); } }, 'json') }); $('form').submit(function(e) { e.preventDefault(); $.post(location, $(this).serialize(), function(d) { $('span').text(d.exp); $('[name="check"]').val(''); alert(d.msg); }, 'json') }); }); </script> </head> <body> <form> <input name="text" value="Text" /> </form> <label>Сколько: <span><?=check()?></span>=?</label> <input name="check" /> <button>Проверка</button> </body> </html> |
Однако казалось легче изначально :)
Обманчивая и страшная штука этот JS. Пойду экспериментировать. Цитата:
|
Цитата:
И у вас проблемы прежде всего в этом, в структуре кода вашего, а не в JS. |
Часовой пояс GMT +3, время: 22:26. |