Обработка HTML форм в CGI
Существуют два метода отправки данных на сервер - 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&married=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'};
Если Вы не нашли что искали, то рекомендую воспользоваться поиском по сайту:
|