В прошлых выпусках нашей рассылки мы разобрались, каким образом
скрипту передаются параметры запроса, каким образом скрипт их
принимает и как сделать HTML-форму - для того, чтобы конечный
пользователь мог вручную вводить параметры и передавать их скрипту.
Мы уже изучили всю основную информацию по этому поводу. Для того,
чтобы закончить с передачей параметров, нам осталось
только одно маленькое "но"...
Прием параметров CGI-скриптом - окончание
В прошлом выпуске рассылки (про веб-формы) я упомянул, что броузер,
передавая строку запроса, не передает все символы "как есть", а заменяет
"не-ASCII" и некоторые ASCII-символы последовательностью других.
В этом выпуске мы поговорим про это подробнее.
Для начала создадим удобный тестовый скрипт, который будет нам показывать
не просто строку запроса, а уже разобранные параметры. Для этого применим
фрагмент разбора параметров из позапрошлого выпуска рассылки. Чтобы сделать
из него полноценный скрипт, надо совсем немного - добавить к нему
код вывода результатов работы:
Предположим, что Вы назвали этот скрипт test1.cgi и разместили
в своей папке cgi-bin, и он доступен у Вас на веб-сервере по URL
http://host/cgi-bin/test1.cgi
Теперь создадим простую веб-страничку с HTML-формой для передачи параметров этому
скрипту, состоящую для начала всего лишь из одного элемента ввода - текстовой строки:
Сохраните эту страничку в файл html с любым именем
(если URL в параметре ACTION этой формы - абсолютный, как здесь,
то Вы можете ее разместить где угодно, даже на локальном компьютере).
Открыв ее, Вы сможете набирать в поле ввода различные значения
параметра param1, отправлять их на серверный скрипт и смотреть результат
его работы.
Попробуйте передавать скрипту строчки, содержащие английские буквы, русские
буквы, различные знаки. При этом Вы заметите, что английские буквы
и некоторые знаки отображаются нашим скриптом "как есть", а вместо других
скрипт выдает последовательность в виде %XX.
Все дело в том, что строка запроса может содержать "как есть" только символы
таблицы ASCII, и то не все. Также строка запроса не может разрываться пробелами.
Символы '&' и '=' имеют в строке запроса специальное назначение
как разделители (см. прошлые выпуски), и передача их "как есть"
также невозможна.
А поскольку эти символы в параметрах передать все-таки надо, броузер
их заменяет на последовательность таких символов, которые могут
содержаться в строке запроса. В качестве такой последовательности служит
конструкция %XX, где XX - шестнадцатеричный код символа (цифры 0-9 и
буквы A-F).
Пробелы передаются несколько по-иному: они просто заменяются на
знак '+'. А "настоящий" знак '+' передается в виде последовательности
%XX (конкретно - %2B).
Соответственно, наш скрипт должен производить обратное преобразование
- из того, что передал ему броузер, делать то, что пользователь имел
в виду. :-)
А если поконкретнее :-), то скрипт должен:
Заменять все символы '+' на пробелы.
Заменять все последовательности '%XX' на символы с соответствующими
кодами XX.
Причем эти преобразования надо делать со значениями уже разобранных параметров,
т.е. строками, уже заведомо содержащими "пользовательские" данные без
разделителей.
Для таких замен удобно применить perl-овские операторы транслитерации ~tr///
и замены ~s///. Их мы подробно рассмотрим позже, когда будем изучать
работу со строками в Perl.
Первая строка заменяет плюсы на пробелы, а вторая - последовательности
с кодами символов на символы. Добавив эти строки в вышеприведенный
скрипт перед строкой
$PARAM{$name}=$value;
мы "дадим" ему полноценный законченный код для приема параметров
запроса.
"Каркас" CGI-скрипта
Почти любой CGI-скрипт можно условно представить состоящим из двух
частей - собственно "полезного кода", который делает основную работу,
и "обрамления", который занимается "общением" с внешним миром скрипта,
точнее - с веб-сервером: принимает параметры запроса и
другую информацию и выдает результат клиенту.
Вторая часть скрипта в общем-то выполняет похожие функции в самых
разных скриптах и различается незначительно.
Собрав воедино все наши предыдущие примеры, мы можем
сделать своеобразный "каркасный код" для большинства наших
последующих скриптов:
#!/usr/bin/perl
$m=$ENV{'REQUEST_METHOD'};
#Если метод - POST, то получаем параметры со станартного ввода,
#Иначе - из переменных среды
if ($m eq 'POST') {$s=}
else {$s=$ENV{'QUERY_STRING'};};
#Обрабатываем принятые параметры и создаем хэш %PARAM
pars=split("&",$s);
foreach $item(@pars) {
($name,$value)=split("=",$item);
$value=~tr/+/ /;
$value=~ s/%(..)/pack("c",hex($1))/ge;
$PARAM{$name}=$value;
};
##################################################
# Здесь размещается собственно "рабочий" код
##################################################
print "Content-Type: text/html\n\n";
print $out;
Имея такую заготовку, Вы можете начинать создание нового скрипта
сразу "по существу", экономя время и силы за счет отказа от
"изобретения велосипеда". :-)
На сегодня все. В следующем выпуске рассылки мы более подробно
остановимся на таком важном аспекте CGI-программирования, как работа
со строками в Perl.