Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Эссе - посвящение кэптчуризации )
 
 автор: sim5   (11.10.2008 в 15:32)   письмо автору
104.3 Кб
 
 

Перефразируя знаменитое "быть или не быть" на "бот или не бот", начнем ;-) Всем начинающим, и просто для разминки, предлагается.) Вот еще одно предложение для "бота" - анимированная каптча в форме со случайными именами полей, спрятанная во фрейм. Пишется "с колес", и как пример, и если что, можно править.
Сперва сделаем каптчу. Для этого потребуется класс GIFEncoder.class.php (в приложении). Класс позволяет строить анимацию из последовательности GIF-изображений находящихся на диске, либо в памяти. Первый способ не годится, так как придеться писать механизм сборщика мусора изображений, которые могут остаться при закрытии браузера пользователем. Можно конечно всем пользователям одно "кино" показывать, но тогда это уже не каптча будет, а мелодрама.)
Для работы с ресурсами изображений будем буферизировать вывод, и таким образом получать результат работы GD (память ресурса). В предложенном ниже используется всего два кадра, но возможно наличие и более кадров, поэтому пишем функцию возвращающую нам память gd-ресурса:
<?
function getMemory($res$type) {
  
ob_start();
  switch(
strtolower($type)) {
    case 
"gif"imagegif($res);
    break;
    case 
"jpg"imagejpeg($res);
  }
  
$mem ob_get_contents();
  
ob_end_clean();
  return 
$mem;
}
?>

В функцию будем передавать дескриптор ресурса и тип изображения. Хотя для gif-анимации тип jpеg не требуется, будем использовать его для "облегчения веса" кадров анимации. Если это не критично, то можно отказаться от этого промежуточного шага. Функция будет возвращать бинарные данные кадров gif-анимации, что нам и нужно.
Создаем анимацию:
<?
//продолжаем сессию, она нам потребуется в дальнейшем
session_start();
//параметры изображения
$width 84;
$height 24;
//размер анимированного бокса
$box 10;
//массив кадров анимации
$frames = array();
//создаем изображение с фоном
$im imagecreate($width,$height);
imagecolorallocate($im224208224);
//нарисуем прямоугольники-мусор
for($i=0;$i<4;$i++) {
  
$dc imagecolorallocate($imrand(0,255), rand(0,255), rand(0,255));
  
imagerectangle($imrand(0$width/), rand(0$height/), rand($width/2$width), rand($height/2$height), $dc);
}
//немного пошумим
for($i=0;$i<500;$i++) {
  
$dc imagecolorallocate($imrand(0,255), rand(0,255), rand(0,255));
  
imagesetpixel($imrand(0,$width), rand(0,$height), $dc);
}
//запишем jpeg шаблон в память
$dist getMemory($im"jpg");
//создаем изображение из шаблона
$im imagecreatefromstring($dist);
//добавим бордюр, это нам тоже пригодиться в дальнейшем
//это у нас будет кнопка submit "в рамочке" :)
$dc imagecolorallocate($im0,0,0);
imagerectangle($im00$width-1$height-1$dc);
//приводим к индексированной палитре
//так облегчаем "в весе" кадры анимации
imagetruecolortopalette($imfalse128);
//сохраняем первый кадр анимации в GIF87a
$frames[] = getMemory($im"gif");
//создаем второй кадр анимации
//это цвет анимированного бокса в анимации
//не стоит брать по максимальному (255)
//так как на ЖК мониторах он может сливаться с фоном
$dc imagecolorallocate($imrand(0,148), rand(0,148), rand(0,148));
//получаем координаты случайного положения бокса
$x rand(0$width - ($box+1));
$y rand(0$height - ($box+1));
//рисуем бокс по которому предложим пользователю "жмахать"
imagerectangle($im$x$y$x+$box$y+$box$dc);
//сохраняем второй кадр анимации в GIF87a
$frames[] = getMemory($im"gif");
//указываем длительность кадров
$loops = array(35,35);
//подключаем класс
include "GIFEncoder.class.php";
//передаем аргументы и указываем классу, 
//что кадры берем как бинарные данные
$gif = new GIFEncoder($frames$loops02000"bin");
//вывод анимации
header("Content-type: image/gif");
echo 
$gif->GetAnimation();
//освобождаем память
imagedestroy($im);
unset(
$dist);
unset(
$frames);
//запоминаем положение координат анимированного бокса
//и время старта анимации для дальнейшего использования
$_SESSION['coords'] = array();
$_SESSION['coords']['x'] = $x;
$_SESSION['coords']['y'] = $y;
$_SESSION['coords']['time'] = time();
?>

Кода первой части эссе.

  Ответить  
 
 автор: Николай2357   (11.10.2008 в 16:51)   письмо автору
 
   для: sim5   (11.10.2008 в 15:32)
 

Хотя я ярый противник капчи как таковой, тема всё равно интересная. А вот вопрос, флэш боты умеют читать? На флэшках можно вообще веселые капчи делать...

  Ответить  
 
 автор: sim5   (11.10.2008 в 16:54)   письмо автору
 
   для: Николай2357   (11.10.2008 в 16:51)
 

Уже можно получать содержимое флешь. Ну не обязательно каптчу, можно другие "усложнения" предложить. Недавно mihdan давал ссылку на статью посвященную этому, вот перекурю и во второй части объеденю все в кучу. А уж что использовать, а что нет, или стоит ли вообще использовать, то это вопрос риторический :)

  Ответить  
 
 автор: sim5   (11.10.2008 в 18:26)   письмо автору
 
   для: sim5   (11.10.2008 в 15:32)
 

Вторая часть. Назовем скрипт каптчи, как secret.pnp, и его с классом поместим, например, в папку include, тогда пропишем в .htaccaess следующее:
RewriteEngine on
RewriteRule image/button.ims /include/secret.php

Будем получать данные от пользователя, для примера хватит и двух, не важно каких, пусть будет ник и адрес мыла. На странице, которая выводит форму для пользователя, выводим следующий код:
<iframe src="getuser.php" 
onLoad="window.document.getElementById('view').innerHTML =  frm.document.body.innerHTML;" 
frameborder='0' width='0' height='0' name='frm' id='frm'></iframe>
<div id='view' style="text-align: center;"></div></div>

В этот контейнер спрячем форму пользователя, и это будет работать как AJAX. Назовем файл обработчика формы как getuser.php, а его содержимое:
<?
session_start
();
//размер анимированного бокса
$box 10;
//период времени запроса анимации (сек)
$looptime 6;
//функция создания случайных имен для полей формы
function formGet($name) {
  
$_SESSION['elemets_form'] = array();
  foreach(
$name as $val) {
    
$_SESSION['elemets_form'][$val] = md5(uniqid(rand(),1));
  }
  return 
$_SESSION['elemets_form'];
}
//генерируем случайные имена полей формы
if (!isset($_SESSION['elemets_form']) && !$_SESSION['loock']['usr']) $elm formGet(array("name","email","sheck","submit"));
//ошибка заполнения полей, для примера просто булевый тип
$error false;
//ошибка координат кнопки при отправке формы
$error_coor false;
//для сокращения записей
$elemets = &$_SESSION['elemets_form'];
$coords  = &$_SESSION['coords'];
//определяем переменные, имена полей формы определяем по массиву
$check = isset($_POST[$elemets['sheck']]) ? 0;
$coorx = isset($_POST[$elemets['sheck']]) ? intval($_POST[$elemets['submit'].'_x']) : false;
$coory = isset($_POST[$elemets['sheck']]) ? intval($_POST[$elemets['submit'].'_y']) : false;
$name  = isset($_POST[$elemets['name']])  ? trim($_POST[$elemets['name']]) : "";
$mail  = isset($_POST[$elemets['email']]) ? trim($_POST[$elemets['email']]) : "";
//отправку поля проверяем по скрытому полю, можно и сократить
if ($check) {
  
//проверяем значения полученных полей
  
if (!$name$error true;
  if (!
$mail || !checkMail($mail)) $error true;
  
//если все ОК проверяем запрос
  
if (!$error && $coorx && $coory) {
    
//если время запроса капчи больше установленного
    
if (time() - $coords['time'] > $looptime) {
      
//удаляем переменные (можно делать на странице error.php)
      
unset($_SESSION['coords']);
      unset(
$_SESSION['elemets_form']);
      
//блокируем доступ на период сессии
      
$_SESSION['loock']['usr'] = 1;
      
//переход на страницу ошибок
      
header("location: error.php");
    }
    
//проверяем координаты каптчи
    
if ($coorx >= $coords['x'] && 
      
$coorx <= $coords['x'] + $box &&
      
$coory >= $coords['y'] && 
      
$coory <= $coords['y'] + $box) {
      
//все ОК, пишем данные в базу
      //.......
      //удаляем переменные
      
unset($_SESSION['coords']);
      unset(
$_SESSION['elemets_form']);
      
//блокируем доступ на период сессии
      
$_SESSION['loock']['usr'] = 1;
      
//и переход ...
      
header("location: ok.php");
    } else {
      
//координаты выбора капчи не равны установленным, даем еще 2 попытки 
      
$coords['send_loop'] = (!isset($coords['send_loop'])) ? $coords['send_loop'] -= 1
      
//если попытки закончились
      
if (!$coords['send_loop']) {
        
//удаляем переменные
        
unset($_SESSION['coords']);
        unset(
$_SESSION['elemets_form']);
        
//блокируем доступ на период сессии
        
$_SESSION['loock']['usr'] = 1;
        
//переход на страницу ошибок
        
header("location: error.php");
      } else {
        
//предлагаем повторить отправку формы
        
$error_coor true;
      }
    }
  }
}
//вывод формы по умолчанию и ошибках
if (!$check && !$_SESSION['loock']['usr'] || $error || $error_coor) {
//обновление имен полей формы
if ($error || $error_coor$elm formGet(array("name","email","sheck","submit"));
echo 
"
<script>
function getDot() {
  //функция периодически меняющая анимацию каптчи
  //которая служит для отправки формы
  document.getElementById('im').src = 'image/button.ims';
}
//установленный период смены анимации
onLoad = setInterval('getDot()',"
.$looptime."000);
</script>
<form action=\"getuser.php\" method=\"post\" onsubmit=\"this.setAttribute('target','frm');\">
Имя: <input type=\"text\" name=\""
.$elm['name']."\" value=\"".htmlspecialchars($name)."\"><br>
e-mail: <input type=\"text\" name=\""
.$elm['email']."\" value=\"".$mail."\"><br>
<input type=\"hidden\" value=\"1\" name=\""
.$elm['sheck']."\">
Для корректной отправки формы, нажмите моргающую область кнопки 
<input id=\"im\" type=\"image\" name=\""
.$elm['submit']."\" src=\"image/button.ims\" border=\"0\">
</form>"
;
exit;
}
?>

Вот собственно и все эссе.

  Ответить  
 
 автор: ddhvvn   (11.10.2008 в 19:01)   письмо автору
 
   для: sim5   (11.10.2008 в 18:26)
 

Я вот, например, узнал про класс, генерирующий анимгифы!

Браво! А когда выйдет Ваше собрание сочинений? ;-))

  Ответить  
 
 автор: sim5   (11.10.2008 в 19:18)   письмо автору
 
   для: ddhvvn   (11.10.2008 в 19:01)
 

Ну во-первых про класс я тоже не знал, узнал случайно (хотя подозрение, что он уже "живет", конечно же были), благодаря одному из посетителей форума. ) Что касается сочинений, то их не будет, потому как нет в наличии :)

  Ответить  
 
 автор: ddhvvn   (11.10.2008 в 19:26)   письмо автору
 
   для: sim5   (11.10.2008 в 19:18)
 

Я даже собирался написать такой класс сам, в учебных целях.

Но что-то не пошло, потом стало некогда... теперь точно не напишу ))

  Ответить  
 
 автор: sim5   (11.10.2008 в 19:33)   письмо автору
 
   для: ddhvvn   (11.10.2008 в 19:26)
 

Лучше опоздать, чем долго собираться :))

  Ответить  
 
 автор: Николай2357   (11.10.2008 в 20:37)   письмо автору
 
   для: sim5   (11.10.2008 в 19:33)
 

А как вам такая капча? :)))

  Ответить  
 
 автор: sim5   (11.10.2008 в 20:42)   письмо автору
 
   для: Николай2357   (11.10.2008 в 20:37)
 

ОгрОООмная :) На флешке можно конечно наворотить до бессовестного ;-) Можно, конечно, если хочется, задействовать Ming.

  Ответить  
 
 автор: Николай2357   (11.10.2008 в 20:51)   письмо автору
 
   для: sim5   (11.10.2008 в 20:42)
 

Не, а если серьёзно, я только сейчас (благодаря Вам) задумался - а почему не используют флэш для этого? Файлик довольно маленький получается, флэш практически у всех есть... А ведь это гораздо удобнее, чем знаки и цифры вводить. Тыкай мышкой туда - сюда и все... Какие то есть подводные камни...

  Ответить  
 
 автор: sim5   (11.10.2008 в 20:58)   письмо автору
 
   для: Николай2357   (11.10.2008 в 20:51)
 

Вот уверенность, что флешь практически у всех есть ошибочна. Ну например, практически все мои постояннные клиенты, это женщины, и многие из них даже не знают такого "флешь", а если и знают, то ассоциируют это пластмассовой штучкой. Выходят в сеть украдкой с мета работы, и то что всем им админ флешь проигрыватель установил, так это еще вопрос. Как вы думаете, что такой пользователь будет делать, увидев пугающую надпись - "Для нормального отображения этой страницы..."? Нельзя этого исключать, а значит нужен и второй вариант (запасной:)).

  Ответить  
 
 автор: Николай2357   (11.10.2008 в 21:07)   письмо автору
 
   для: sim5   (11.10.2008 в 20:58)
 

Ну если админ запретил на работе по сайтам регится, то из чувства солидарности нужно это делать :))) А вот то, что 70% юзерей плюют на регистрацию (это мегапорталов конечно не касается) если видят кривые цифры - доказанный факт. Так что не известно, где найдешь, где потеряешь. А в принципе ни кто не запрещал ставить и запасной вариант, или на выбор... Надо разобраться с этим вопросом на досуге.

  Ответить  
 
 автор: sim5   (11.10.2008 в 21:19)   письмо автору
 
   для: Николай2357   (11.10.2008 в 21:07)
 

Я тоже не любитель разбираться в "кривых цифрах и буквах", а предложнной анимации вполне хватит. Ведь можно сделать разноаобразную анимацию, и соответсвенно постоянно предлагать другое действие пользователю. Это ведь не так сложно сделать с технической точки зрения. Главное чтобы фантазия была. А вот к примеру, в IE7 по умолчанию и JS отключен. В данном случае, после первой попытки об этом можно информировать пользователя, а инструкция по его включению не так сложна :)
А "кривые цифры" и Рапида убрала, и другие файлообменники...

  Ответить  
 
 автор: Николай2357   (11.10.2008 в 22:24)   письмо автору
 
   для: sim5   (11.10.2008 в 21:19)
 

Да, такие капчи нам нужны!!! Спасибо, мне очень понравилося принцип. Только вот со штакесом проблемы, не видит замену почему то.
Если кому интересно как выглядет, вот: капча

  Ответить  
 
 автор: sim5   (11.10.2008 в 22:28)   письмо автору
 
   для: Николай2357   (11.10.2008 в 22:24)
 

Вы пример выставили, а функцию checkMail(), которая у меня для примера просто, тоже написали ?)) Ошибку же выдает.
PS. И уж добавьте тогда и страницы переходов, чтобы бага не было, типа "Фиг, вы не угадали" и "Тоже фиг, но отгадали" хотя бы :)

  Ответить  
 
 автор: Николай2357   (11.10.2008 в 22:36)   письмо автору
 
   для: sim5   (11.10.2008 в 22:28)
 

Прошу пардона, чесно говоря меня только принцип построения интересовал. А у меня не выдает ошибок... Щас поправлю.

  Ответить  
 
 автор: sim5   (11.10.2008 в 22:39)   письмо автору
 
   для: Николай2357   (11.10.2008 в 22:36)
 

Ну там же проверка майла, и, если что-то ввести неверно, то получим баг. Что касается реврайта, то может не в том прописали ?) Проблем не должно быть, я хоть и с колес писал, но проверял смену анимации.

  Ответить  
 
 автор: Николай2357   (11.10.2008 в 23:33)   письмо автору
 
   для: sim5   (11.10.2008 в 22:39)
 

Да бог с ним, с реврайтом. Это не главное. Можно разобраться. Там другие проблемы.
Я не пойму, как переход задуман хидером, если это аякс. Я хотел написать чтото типа этого
<?
echo 
<script>      
window.location.href='fig.php'
</script>"
;
так выяснилось, что имен у элементов формы нет. Причем в лисе пару раз появлялись, щас вообще правды добиться не могу. Опера ничего не видит. Я по этому ошибку и не увидел сразу.

  Ответить  
 
 автор: Николай2357   (12.10.2008 в 04:42)   письмо автору
 
   для: Николай2357   (11.10.2008 в 23:33)
 

Так до конца и не разобрался с блокировками... И в опере не работает...
Завтра.

  Ответить  
 
 автор: sim5   (12.10.2008 в 20:48)   письмо автору
 
   для: Николай2357   (12.10.2008 в 04:42)
 

Разобрался. Есть смена капчи по указанному времени, тут картина такая была - IE меняет, Opera нет (в Опера вы и считали, видимо, это за не работу htaccess, но ведь изображение появляется). Причина - кеширование. Неверно логику файла обработки формы написал, поэтому - в Опера работает "AJAX", а в IE нет. Но все это можно решить разделением сценариев, меня интересует вопрос, почему в одном не хочет, если на шаблонах все работает. С этим разберусь, выставлю.

  Ответить  
 
 автор: sim5   (12.10.2008 в 06:58)   письмо автору
 
   для: Николай2357   (11.10.2008 в 23:33)
 

Имена у формы есть, они обновляются случайно при ошибках ввода. А вот про переход да, упустил, делать надо так:
<?
echo "<script>parent.location.href='fig.php';</script>";
exit;

Посмотрел работу уже во фрейме (где-то перед этим ошибка, что мешает выполнению JS сценария), да, нет обновление капчи по запросу, есть и еще... Где-то напорол, сейчас на свежую голову проверим.)

PS. Сделайте пока пример без фрейма. А дальше я разберусь где накосячил, выставлю впоследствии изменения.

  Ответить  
 
 автор: sim5   (12.10.2008 в 21:38)   письмо автору
 
   для: sim5   (11.10.2008 в 15:32)
 

В общем измененная часть вывода. Ошибку я допустил в том, что не разделил по запросу код, плюс сама логика обработки. Сейчас все работает в Opera, FF, Safari, а вот в IE нет обработки POST запроса. Пока не знаю почему, этот механизм я использую давно и проблем не было ни в одном из этих браузеров. Может потому что он "ослом" называется :), но на шаблонах работает все, но там и вся структура кода другая. С этим разберусь, ну или кто другой заметит.
Есть неприятный эффект в Опера - обновление каптчи по таймеру, приводит к перезаписи адресной строки в окне, что не смертельно, но не приятно (вот и думай после такого кто из них недобраузер:)). Вот изменения. В src фрейма на странице его вывода, нужно добавить любой параметр. Тут проверяем и блокировку на переиод сессии.
<? 
session_start
();
if (!isset(
$_SESSION['loock'])) $_SESSION['loock'] = array();
//период времени запроса анимации (сек) 
$looptime 6;
if (!
$_SESSION['loock']['usr']) { ?>
<script> 
    function getDot() {
     //обходим кеширование  
     document.getElementById('im').src = 'image/button.ims?' + Math.random(); 
    }
    onLoad = setInterval('getDot()',".$looptime."000); 
   </script>
<iframe src="getuser.php?gt"  
onLoad="window.document.getElementById('view').innerHTML =  frm.document.body.innerHTML;"  
frameborder="0" width="0" height="0" name="frm" id="frm"></iframe>
<div id="view" style="text-align: center;"></div>
<? ?>

Устанавливаем блокировку на переиод сессии, удаляем массивы из сессии в файлах ошибки и перехода после удачной обработки:

<?
session_start
();
//удаляем переменные 
unset($_SESSION['coords']); 
unset(
$_SESSION['elemets_form']); 
//блокируем доступ на период сессии 
$_SESSION['loock']['usr'] = 1;
echo 
"Error";
?>

Ну и сам обработчик:
<?
session_start
(); 
//функция создания случайных имен для полей формы 
function formGet($name) { 
  
$_SESSION['elemets_form'] = array(); 
  foreach(
$name as $val) { 
    
$_SESSION['elemets_form'][$val] = md5(uniqid(rand(),1)); 
  } 
  return 
$_SESSION['elemets_form']; 
}
//это загрузка по запросу фрейма
//если прописать код без проверки типов запросов,
//то буду созданы две копии объектов 
if (isset($_GET['gt'])) {
//генерируем случайные имена полей формы
$elm formGet(array("name","email","sheck","submit")); 
//вывод формы по умолчанию
echo "
   <form action=\"getuser.php\" method=\"post\" onsubmit=\"this.setAttribute('target','frm');\"> 
   Имя: <input type=\"text\" name=\""
.$elm['name']."\"><br> 
   e-mail: <input type=\"text\" name=\""
.$elm['email']."\"><br> 
   <input type=\"hidden\" value=\"1\" name=\""
.$elm['sheck']."\"> 
   Для корректной отправки формы, нажмите моргающую область кнопки  <br>
   <input id=\"im\" type=\"image\" name=\""
.$elm['submit']."\" src=\"image/button.ims\" border=\"0\"> 
   </form>"
;
   exit;
}

//обработка полей формы
if (isset($_POST[$_SESSION['elemets_form']['sheck']])) {
  
//размер анимированного бокса 
  
$box 10;
  
//период запроса каптчи
  
$looptime 6
  
//ошибки заполнения полей 
  
$error ""

  
$coorx intval($_POST[$_SESSION['elemets_form']['submit'].'_x']); 
  
$coory intval($_POST[$_SESSION['elemets_form']['submit'].'_y']); 
  
$name  trim($_POST[$_SESSION['elemets_form']['name']]); 
  
$mail  trim($_POST[$_SESSION['elemets_form']['email']]); 

  if (!
$name$error .= "Error Name. ";
  if (!
$mail$error .= "Error Mail.";
  
$dot = ($coorx >= $_SESSION['coords']['x'] &&  
          
$coorx <= $_SESSION['coords']['x'] + $box && 
          
$coory >= $_SESSION['coords']['y'] &&  
          
$coory <= $_SESSION['coords']['y'] + $box) ? true false;

    
//если время запроса капчи больше установленного 
    
if (time() - $_SESSION['coords']['time'] > $looptime) { 
      
//переход на страницу ошибок 
      
echo "<script>parent.location.href='error.php';</script>";
      exit; 
    } 
    
//проверяем координаты каптчи 
    
if (!$error) { 
      if (
$dot) {
        
//все ОК, пишем данные в базу 
        //....... 
        //и переход ... 
        
echo "<script>parent.location.href='ok.php';</script>";
        exit;
      } else { 
        
//координаты выбора капчи не равны установленным, даем еще 2 попытки  
        
$_SESSION['loock']['send'] = !isset($_SESSION['loock']['send']) ? $_SESSION['loock']['send'] -= 1;  
        
//если попытки закончились 
        
if (!$_SESSION['loock']['send']) { 
          
//переход на страницу ошибок 
          
echo "<script>parent.location.href='error.php';</script>";
          exit; 
        } else { 
          
//предлагаем повторить отправку формы
          
$error .= "Please, still attempt.";
        }
     } 
   } 
  
//вывод формы при ошибках 
  
if ($error) { 
    
//полям формы новые имена
    
$elm formGet(array("name","email","sheck","submit")); 
    echo 
"
     <p>
$error</p>
     <form action=\"getuser.php\" method=\"post\" onsubmit=\"this.setAttribute('target','frm');\"> 
     Имя: <input type=\"text\" name=\""
.$elm['name']."\" value=\"".htmlspecialchars($name)."\"><br> 
     e-mail: <input type=\"text\" name=\""
.$elm['email']."\" value=\"".$mail."\"><br> 
     <input type=\"hidden\" value=\"1\" name=\""
.$elm['sheck']."\"> 
     Для корректной отправки формы, нажмите моргающую область кнопки  <br>
     <input id=\"im\" type=\"image\" name=\""
.$elm['submit']."\" src=\"image/button.ims\" border=\"0\"> 
     </form>"
;
     exit; 
  }
}
?>

PS. JS сценарий вызова обновления каптчи вынесен из вывода самой формы, и помещен в заголовок шапки основной страницы (можно в подключаемый JS).

  Ответить  
 
 автор: Николай2357   (12.10.2008 в 23:25)   письмо автору
 
   для: sim5   (12.10.2008 в 21:38)
 

Только сел поразбираться - на тебе новая версия! :))
Сильно вникнуть не успел, но в опере так и не работает.

>(в Опера вы и считали, видимо, это за не работу htaccess, но ведь изображение появляется).

Нет, не считал. Не работает реврайт у меня, и сегодня тоже. Но я не разбирался почему, это не главное. А изображение появляется, потому что я пути поменял. В ослике не смотрел, расстроился из-за оперы (любимый браузер) :)))

Может в реврайте причина, хотя причем тут... А мозила на фигу не сбрасывает.

Еще огорчило то, что форма теперь на php.
А я действительно загорелся капчу веселую сделать. На флэшке. Вот они вместе (Ваша как запасной вариант) изумительно бы работали. Но я еще доберусь! :)))

Может я поставил что не так... Такое очучение, что опера JS не видит по второиу разу, но с кэшем вроде боролись...

  Ответить  
 
 автор: sim5   (12.10.2008 в 23:47)   письмо автору
 
   для: Николай2357   (12.10.2008 в 23:25)
 

Насчет реврайт. Если бы он не работал, то изображение бы не выводилось вообще, если вы конечно с ним пробовали. То что это кеширование было в Опера, выдно сразу - при наступлении времени обновления каптчи, на ней наблюдается задержка небольшая (как бы пауза), а затем анимация возобновляется - значит кеш. Добавил к пути изображения рандомное число и все. Можно попробовать и заголовки соответсвующие передавать в файле выводящем каптчу. Сделаем так - перенесем JS сценарий из форм на страницу (см. сейчас изменю код выше).
А что значит "Еще огорчило то, что форма теперь на php"?

PS. Внес изменения, пробуйте. Сейчас будет работать, кроме в IE - не примает он форму, и если просмотреть саму сессию, то нет измнений касающихся полей фрмы, не проходит запрос с формы. Выясню, потом.

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 00:07)   письмо автору
 
   для: sim5   (12.10.2008 в 23:47)
 

>Если бы он не работал, то изображение бы не выводилось вообще, если вы конечно с ним пробовали
Так оно и не выводится. Я же написал, что пути поменял. Может в этом дело? Сейчас новую попробую.
А на счет формы - многие вставляют каптчу в HTML, а обработчики готовые берут. Вот только что пример был про почту. Так вот лучше было, когда форма на чистом HTML...

  Ответить  
 
 автор: sim5   (13.10.2008 в 00:17)   письмо автору
 
   для: Николай2357   (13.10.2008 в 00:07)
 

А у меня она на "грязном" HTML? :) Просто ее выдает РНР, это ответ его, такой же как и в AJAX происходит. В данном случае при ошибках ввода, не будет перезагрузки страницы, а перезагружаться будет только форма вместе с каптчей. Можно задействуя AJAX написать, но стоит ли, только ради этого? Если же вы используете AJAX, то нет проблем, пишите на чистом HTML, но и форма будет открыта. В примере же, она как никак спрятана во фрейм, хотя достучаться до нее конечно можно, но как никак... ;-)
Я сейчас в Опера и у меня все работает.

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 00:35)   письмо автору
 
   для: sim5   (13.10.2008 в 00:17)
 

Может я не так чего объясняю...

>Я сейчас в Опера и у меня все работает.

Вот я поставил на хостинг : каптча
Картинку видно и анимацию, вопросов нет.
Но если нажать на неё, она исчезнет. В мозиле я хоть видел, что к чему, в фаербуге. Так сегодня она в мозиле работает...
А про форму, не понял я теперь.
<?  
session_start
(); 
if (!isset(
$_SESSION['loock'])) $_SESSION['loock'] = array(); 
//период времени запроса анимации (сек)  
$looptime 6
if (!
$_SESSION['loock']['usr']) { ?>
вот это как с расширением html сохранить? Вот вчерашняя версия - другое совсем дело. Или я не понимаю чего?

  Ответить  
 
 автор: sim5   (13.10.2008 в 00:47)   письмо автору
 
   для: Николай2357   (13.10.2008 в 00:35)
 

Если нажать на нее она исчезнет, это потому, что у вас сейчас не работает обновление каптчи. Она должна обновляться через каждые 6 секунд, а у вас этого нет. Вы взяли уже измененный код, где на странице вывода фрейма помещен JS-сценарий таймера обновления каптчи, и он же убран из вывода во фрейм?
Зачем это сохранять с расширением HTML? Хотя если охота, то сохраняйте, если ваш Апач обрабатывает РНР код в HTML файлах.

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 00:56)   письмо автору
 
   для: sim5   (13.10.2008 в 00:47)
 

>странице вывода фрейма помещен JS-сценарий таймера обновления каптчи, и он же убран из вывода во фрейм?

Сейчас да, хотя и прежний вел себя так же.

>Зачем это сохранять с расширением HTML?
Мне не надо, а вот некоторые товарищи (и их много) хотят капчу в html вставить свой. чтоб не менять ничего. Предрассудки или еще чего, не знаю. Классическая капча это позволяет...

  Ответить  
 
 автор: sim5   (13.10.2008 в 01:09)   письмо автору
 
   для: Николай2357   (13.10.2008 в 00:56)
 

Ну саму каптчу нет проблем вставить, но без всякого фрейма. Посмотрите тут как работает - смена каптчи и возврат ошибок во фрейм. В данный момент я поставил без реврайт, так как не "у себя дома" выставил, и только на время короткое. Будет все работать в Опера.

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 01:15)   письмо автору
 
   для: sim5   (13.10.2008 в 01:09)
 

Чего же я не так сделал... Бум думать.
Bот и обидно, что без фрейма. Можно было бы на флэшке форму сделать и эту альтом. Вот я чего переживаю...

  Ответить  
 
 автор: sim5   (13.10.2008 в 01:16)   письмо автору
 
   для: Николай2357   (13.10.2008 в 01:15)
 

Вы посмотрели пример по ссылке? А то мне надо его с хоста убрать.

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 01:19)   письмо автору
 
   для: sim5   (13.10.2008 в 01:16)
 

да, спасибо.

  Ответить  
 
 автор: sim5   (13.10.2008 в 01:21)   письмо автору
 
   для: Николай2357   (13.10.2008 в 01:19)
 

Удаляем, и спать, а то у нас уже 7:20 утра, а не в одном глазе еще. Поспим немного, и с осликом надо разобраться.

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 01:24)   письмо автору
 
   для: sim5   (13.10.2008 в 01:21)
 

Я думал, что один такой полуночник. У нас 5-20

  Ответить  
 
 автор: sim5   (13.10.2008 в 01:26)   письмо автору
 
   для: Николай2357   (13.10.2008 в 01:24)
 

Это значит Иркутская область примерно?

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 01:28)   письмо автору
 
   для: sim5   (13.10.2008 в 01:26)
 

Новокузнецк. Ладно, действительно на бок пора. До свиданья.

  Ответить  
 
 автор: sim5   (13.10.2008 в 01:31)   письмо автору
 
   для: Николай2357   (13.10.2008 в 01:15)
 

Ну фрейм нужен как контейнер, собственно это тот же AJAX получается. Сама же каптча работать будет без проблем, какая разница ей в чем "обитать". Просто контейнер еще и скрывает от простого просмотра, ну и плюс не надо все перегружать. Сам же фрейм может быть помещен в HTML страницу - тут проблем нет, главное чтобы запрос был к РНР коду, а не к статической странице. Или я вас не понял...

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 01:57)   письмо автору
 
   для: sim5   (13.10.2008 в 01:31)
 

Все, заработало. Теперь точно можно спать идти.

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 08:50)   письмо автору
 
   для: Николай2357   (13.10.2008 в 01:57)
 

>Есть неприятный эффект в Опера - обновление каптчи по таймеру, приводит к перезаписи адресной строки в окне
Еще одна неприятность - в момент подзагрузки изображения она рисует пустой квадратик (кэш то побороли).
А на счет формы - это я вчера с просонок затупил. Увидел php код и в панику. Думал что для рандома из сессии что то для синхронизации берется.
Осталось с ослом разобраться.
ps ну и трфика кушает изрядно, надо как то попробовать с заполнением синхронизировать, что бы обновление запускалось когда все заполнено к примеру или еще как. я попозже помаракую.

  Ответить  
 
 автор: sim5   (13.10.2008 в 09:21)   письмо автору
 
   для: Николай2357   (13.10.2008 в 08:50)
 

Надо с заголовками поэксперементировать. С осликом, тут надо проверить прием POST данных и что они из себя представляют. Без фрейма, если вы попробуете так, будет все работать во всех браузерах. В тоже время, как я уже говорил, такой механизм miniAjax я использую давно и проблем с ним тоже нет у браузеров. Если вы поняли принцип его работы, то можете на чем либо проверить - Ослик без проблем будет реагировать, я на таком miniAjax Гостевую писал.
Значит где-то проблема с возвращаемыми данными. Но более меня интересует реврайт - вы на локальном сервере с ним проверяли, и он работал/нет? Например, у меня под Денвером проблем с этим не наблюдается.

  Ответить  
 
 автор: sim5   (13.10.2008 в 09:50)   письмо автору
 
   для: Николай2357   (13.10.2008 в 08:50)
 

>ну и трфика кушает изрядно, надо как то попробовать с заполнением синхронизировать

Так это без проблем - вешаем события на поля формы и проверяем в JS, если все "all" запускаем итервал. Но смысл тогда от него какой? Ведь и сайт, это необязательное заполение формы на каждой его странице, и из часа в час, изо дня в день...) Если полей у формы много, можно время обновления увеличить.

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 12:26)   письмо автору
 
   для: sim5   (13.10.2008 в 09:50)
 

>Но смысл тогда от него какой? Ведь и сайт, это необязательное заполение формы на каждой его странице, и из часа в час, изо дня в день...)
Так то оно так, только если кто нибудь отвлечется при регистрации, (отойдет на горшок и вообще забудет), то потом его будет ждать "приятный сюрприз". Это с чатами часто бывает. Она фоном так может счетчик накрутить... ой ой.
А реврайт у меня ни дома ри на хостинге работать не хочет. Хотя другие без проблем. Но это я наверное со штакессом намудрил, разберусь попозже.
>Без фрейма, если вы попробуете так, будет все работать во всех браузерах.
Нет,я полностью хочу, с фреймом.

  Ответить  
 
 автор: sim5   (13.10.2008 в 12:34)   письмо автору
 
   для: Николай2357   (13.10.2008 в 12:26)
 

Ну если проблема трафика связана со счетчиком, то можно сей запрос не учитывать. Да и честно сказать, не представляю себе чата, сообщения которого надо отсылать используя каптчу и прочее - это же ужас!) Или имеется ввиду все же регистрация? Регистрация, это серьезный выбор (например, тоже самое - регистрация в ЗАГСе), и о "горшке" ли может быть речь в таком серьезном деле?) Нужно поготавливать себя к такому шагу :)

  Ответить  
 
 автор: Николай2357   (13.10.2008 в 13:08)   письмо автору
 
   для: sim5   (13.10.2008 в 12:34)
 

Я чат для примера привел. вот если чат оставить включенным на ночь, он запросами на обновление может очень много трафика сжечь. Тут так же. Откроет кто -нибудь другое окно и забудет про это. А счетчик тикает... Денежки считает. Что жил - то зря.

>(например, тоже самое - регистрация в ЗАГСе)
Вот хорошая иллюстрация, тут можно до-о-о-о-лго раздумывать перед дверью. И даже паспорт съесть.

  Ответить  
 
 автор: sim5   (13.10.2008 в 15:06)   письмо автору
 
   для: Николай2357   (13.10.2008 в 13:08)
 

Значит надо выбирать из разумного компромисса. Может вообще не стоит устанавливать каптчу, воспользоваться только случайными именами полей? Это я написал после того, как прочитал ссылку, которую mihdan выставил. Подумал, а почему бы и нет? Может вполне хватит случайного наименования полей? А если "умный бот" будет определять такие поля по тексту их: "Имя:", "E-mail:"..., то можно этот текст у полей выводить с помощью JS.
Все определяется нашей фантазией. Ведь ничего не стоит сделать так:
1. Есть массив определяющий (описывающий) случайную анимаровнную каптчу.
2. При каждом выводе формы, включая при ошибках, случайно выбираем такую каптчу, и она не обязательно должна обновляться по времени, а может в каждом конткретном случае иметь новые установки. Например, каптча в виде линейки по которой движется ползунок, и дойдя до определенного положения будет показана область по которой нужно кликнуть.
Следующая может быть просто набором анимированных фигур, и с каждым разом нужно выбрать какую либо из них. Возможна каптча с бегущей строкой текста (слова) которое нужно ввести в поле ввода. Таких вещей со слуйными параметрами можно описать кучу.

  Ответить  
 
 автор: sim5   (14.10.2008 в 23:34)   письмо автору
 
   для: Николай2357   (13.10.2008 в 12:26)
 

Какая-то странная штука получается и пока не могу понять - Ослик как будто и не передает форму, надо запросы браузера отловить, просмотреть. Но потом, работы много помимо РНР. Завтра, максимум послезавтра, я выставлю ссылку, где вы можете полностью просмотреть работу этого примера (ну не совсем этого, а базирующегося на нем), рабочего во всех браузерах. Не только посмотрите, но и сможите проверить, пощелкав и вводя данные. Это самый первый мой сайт, я его сейчас переделываю, и мне кое-что нужно будет проверить на реальном хосте. Поэтому по этой ссылке будет работать "тестовый режим" без реальной записи в базу, так что можете вводить и т.п..

Так вот, как я и говорил раньше, что пример этот работает на скриптах написанных под Smarty. Этот сайт также использует этот шаблонизатор, и в нем таже все работает. А вот теперь какие различия между (и влияет или нет):

1. Все запросы идут через индексный файл (это не влияет на работу)
2. Скрипт разделен на отдельные логические конструкции на несколько скриптов, чего я естественно показывать не буду (?, имитировал, вроде не должно, просто некогда пока полностью это проверить)
3. Изменен механизм передачи переменных между скриптами (пока не проверял, но не думаю, что должен влиять)
4. Соответственно вывод происходит несколько иначе - засчет перхвата шаблонов и вывода их той же конструкцией echo, так это уж никак не может повлиять.

Где-то собака зарыта либо в DOM, либо JS, но если JS, то не пойму что, если такой же использую всегда. Освобожусь чуточку, найду причину, ну или в HTML раздел вынесу вопрос ;-)

  Ответить  
 
 автор: sim5   (15.10.2008 в 17:22)   письмо автору
 
   для: sim5   (11.10.2008 в 15:32)
 

А вот и как заставить это работать в MSIE. Надо сказать, что решение прямо таки революционное! В конструкции echo в самом начале строки пропишите <br> - и вся проблема. :) С чем это связано, пока не знаю. Можно этот тег прописать в целевой DIV, в который контейнер передает свое содержимое после загрузки, чтобы не писать во всех ответах браузреа по POST запросу.
Нужно так же перенести блок проверки координат и времени ответа в условия if (!$error) { ... и if ($dot) { ... соответственно, думаю понимаете почему.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования