Ключевые слова:perl, html, cgi, web, howto, (найти похожие документы)
Date: Mon, 23 Oct 2000 12:18:57 +0400 (MSD)
From: MailList: Perl в примерах
Subject: Обработка HTML форм в CGI
Обработка форм
Николай Матковский (matkovsky@ukrpost.net)
Существуют два метода отправки данных на сервер - GET и POST.
Вот как работает метод GET. После подтверждения пользователем данных
(нажатием кнопки submit), броузер обращается к требуемому CGI-скрипту
- его URL указан в параметре action тега <FORM>, при этом дописывая к
нему строку запроса - несколько пар вида имя=значение; каждое имя -
это имя элемента формы, а значение - эначение этого поля. Для
текстового поля значение - это его текст, для группы переключателей,
объединенных одним именем - значение value активного переключателя,
аналогично для выпадающего списка - значение value активного элемента
<OPTION>. Флажки включаются в список добавляемых в URL пар только в
случае, если он активен: при этом его значение будет on. После этого
броузер обращается к данному URL, при этом строка запроса доступна
скрипту через глобальную переменную QUERY_STRING.
Например, есть форма такого вида:
<form action="http://www.domain.com/cgi-bin/script.cgi" method="GET">
<input type="text" name="name">
<input type="text" name="age">
<input type="checkbox" name="married">
<input type="submit" value=" ok ">
</form>
Браузер дописывает все данные из формы к URL CGI-скрипта, которому эти
данные отправляются - URL, указанные в параметре action тега <FORM>. В
нашем примере будет составлен приблизительно такой URL:
http://www.domain.com/cgi-bin/script.cgi?name=Иван+Иванов&age=32&ma
rried=on
Пару слов о тех символах, что вы видите в это URL. Вопросительным
знаком отделяется собственно URL скрипта от строки запроса - пар с
именами и значниями. Амперсанды (&) отделяют одну пару от другой.
Плюсами заменяются все пробелы в значениях полей.
Метод POST для отправки данных скрипту пользуется его стандартным
вводом (STDIN). При этом web-сервер устанавливает значение глобальной
переменной CONTENT_LENGTH в число байт в строке запроса - количество
данных, переданных скрипту.
Функция get_parameters()
Рассмотрим функцию get_parameters, которая принимает и сортирует
данные, отправленные из HTML-формы.
sub main::get_parameters {
local (*in) = shift;
local ($i, $key, $val);
read(STDIN,$in,$ENV{'CONTENT_LENGTH'});
@in = split(/[&;]/,$in);
foreach $i (0 .. $#in) {
$in[$i] =~ s/\+/ /g;
($key, $val) = split(/=/,$in[$i],2);
$key =~ s/%(..)/pack("c",hex($1))/ge;
$val =~ s/%(..)/pack("c",hex($1))/ge;
$val =~ s/(<P>\s*)+/<p>/ig;
$val =~ s/</</g;
$val =~ s/>/>/g;
$val =~ s/<b>/<b>/ig;
$val =~ s!</b>!</b>!ig;
$val =~ s/<i>/<b>/ig;
$val =~ s!</i>!</b>!ig;
$val =~ s!\cM!!g;
$val =~ s!\n\n!<p>!g;
$val =~ s!\n! !g;
$in{$key} .= "\0" if (defined($in{$key}));
$in{$key} .= $val;
}
return scalar(@in);
}1;
Анализ текста
local (*in) = shift;
local ($i, $key, $val);
Здесь происходит чтение входных и инициализация локальных переменных.
read(STDIN,$in,$ENV{'CONTENT_LENGTH'});
Собственно чтение данных с HTML-формы. В данном случае передача данных
производится при помощи метода GET, поэтому данные считываются со
стандартного входа программы - с дескриптора STDIN. Как уже было
сказано, при передаче данных методом GET сервер устанавливает значение
глобальной переменной окружения CONTENT_LENGTH равным количеству
передаваемых от формы байт. Таким образом, мы читаем
$ENV{'CONTENT_LENGTH'} байт с стандартного входа в переменную $in.
@in = split(/[&;]/,$in);
В этой строке полученные данные разбиваются на пары имя=значение при
помощи функции split. Полученные пары помещаются в массив @in.
После этого для каждой пары выполняются такие действия:
$in[$i] =~ s/\+/ /g;
($key, $val) = split(/=/,$in[$i],2);
$key =~ s/%(..)/pack("c",hex($1))/ge;
$val =~ s/%(..)/pack("c",hex($1))/ge;
Все плюсы заменяются на пробелы (перед отправкой на сервер броузер
заменяет все пробелы на плюсы - мы должны поменять все обратно); Пара
разбивается на две части - имя и значение; каждая из них декодируется
(при передаче данных все символы второй половины таблицы символов
заменяются на свое шеснадцатеричное представление - мы должны
восстановить символы).
$val =~ s/(<P>\s*)+/<p>/ig; # удаление лишних <p>
$val =~ s/</</g; # замена скобок
$val =~ s/>/>/g;
$val =~ s/<b>/<b>/ig; # возвращение скобок для <b> и <i>
$val =~ s!</b>!</b>!ig;
$val =~ s/<i>/<b>/ig;
$val =~ s!</i>!</b>!ig;
$val =~ s!\cM!!g; # удаление лишних \n
$val =~ s!\n\n!<p>!g; # замены пар \n\n на <p>
$val =~ s!\n! !g; # замена \n на пробел
Далее в целях безопасности удаляются все, что может оказаться
нежеланным в полученной информации - теги, специальные символы и пр.
Уничтожаются пустые HTML-параграфы; все скобки '>' и '<' заменяются на
их HTML-представления - < и > во всех случаях, кроме тех, когда
они открывают или зактывают теги <b> или <i>; удаляются лишние символы
переноса строки; группы символов переноса строки (\n) по два
преобразовываюся в тег <p> - начало HTML-параграфа; отдельные символы
\n - в пробелы.
$in{$key} .= "\0" if (defined($in{$key})); $in{$key} .= $val;
И последнее - в ассоциативный массив %in записывается текущая пара.
После выполнения этих операций над всеми парами фукнция возвращает
полученный хеш, ключами которого будут имена параметров, а значениями
- значения этих параметров.
Эта функция предельно проста в использовании - вот пример ее вызова:
&get_parameters(*input);
Функции передается параметр *input - это переменная, в которую следует
записывать входящие данные. После выполнения этой операции хеш %input
будет содержать все пары "имя-значение", готовые к использованию:
$userName = $input{'name'};
$userAge = $input{'age'};
ГУРУ! Помогите, пож. По образцу статьи сделал скрипт поиска пользователя в домене.
cat poisk.html
...
form METHOD="POST" ENCTYPE="multipart/form-data" action="../cgi-bin/poisk.cgi"
Введите фамилию input type="text" name="name"
input type="submit" value=" ok "
...
Программа ldap.pl работает сама по себе отлично. А вот в скрипте последняя выполненная команда
print $val;
дальше тишина.
#!/usr/bin/perl -w
########################################
$program="/usr/local/sbin/ldap.pl";
sub main::get_parameters {
local (*in) = shift;
local ($i, $key, $val);
Мой респект автору за работу. Программированием занимался, а вот столкнулся с необходимостью склепать сайт - по части книги отзывов обломался.
ПХП и ЦЖИ вовсе не освоены. По крайней мере понятно, куда двигаться. Ясно, что весь код не совсем понятен, но из общих прнципов программирования попробуем осилить.Если верно понял, то зто и есть содержание файла script.cgi