Как я и обещал, в этом выпуске мы рассмотрим получение информации
CGI-скриптом.
Какую же информацию могут получить CGI-скрипты?
Во-первых, это параметры запроса скрипта - те данные,
которые прямо передает скрипту клиент (броузер). Работа
большинства скриптов предусматривает передачу им каких-то
параметров. Например, скрипту гостевой книги в виде параметра
может передаваться действие, которое в данный момент требуется
от скрипта - показать содержимое гостевой книги, добавить запись или
вывести форму добавления этой самой записи. В зависимости от значения
этого параметра скрипт гостевой книги проверяет другие переданные
ему параметры - скажем, если требуется добавить запись, то в качестве
параметров запуска должны быть переданы, например, еще и
содержание добавляемой записи, и имя автора записи.
Во-вторых, скрипт может получить определенную информацию
о клиенте и сервере - скажем, IP-адрес клиента, метод вызова скрипта,
строку идентификации броузера, поддерживаемые им языки, установленные
cookie для данного URL, версию серверного ПО и еще много чего
интересного :-)
Согласно стандарту CGI, для передачи информации скрипту используются
переменные среды (их еще называют "переменные окружения") запуска скрипта
и иногда "стандартный ввод" скрипта: если метод HTTP, выбранный клиентом
для запуска скрипта, предусматривает
наличие "тела" HTTP-запроса, то содержимое этого тела запроса
передается скрипту на стандартный ввод. Остальная информация передается
через переменные среды.
Переменные среды доступны Perl-скрипту в виде "стандартного"
хэша %ENV.
Чтобы увидеть, какие переменные среды передает скрипту Ваш веб-сервер,
Вы можете запустить на нем специальный скрипт, который просто
считывает все свои переменные среды и выдает их Вам в броузер:
Как Вы увидите, с помощью переменных среды скрипту передается довольно
много информации.
В свое время я собрал "до кучи" и систематизировал переменные
среды CGI в своеобразную статью-справочник, которую Вы можете
найти здесь.
Там же есть и описание переменных среды CGI, "специфичных" для сервера Apache
(который является самым распространенным на WWW) и для скриптов,
вызываемых через SSI.
Передача скрипту параметров вызова
А пока давайте рассмотрим, каким образом скрипту передаются параметры
вызова.
В подавляющем большинстве случаев для вызова CGI-скриптов
используются один из двух HTTP-методов - GET или POST.
В зависимости от метода вызова, параметры запроса передаются веб-сервером
скрипту по-разному.
Метод вызова скрипта передается CGI-скрипту в переменной среды
REQUEST_METHOD. Рассмотрим подробнее эти методы, преимущества
и недостатки каждого.
Метод "GET"
Метод GET - это "обычный", наиболее часто используемый метод.
С помощью этого метода запрашивается любой веб-ресурс с сервера.
При использовании этого метода, броузер передает параметры
(если это надо) в самом URL скрипта после знака '?'.
Таким образом, при вызове скрипта этим методом передаваемые скрипту
параметры фактически являются частью URL.
Из этого и вытекают как преимущества, так и недостатки этого метода
вызова скрипта. Основным преимуществом этого метода является то,
что запрос скрипта может быть выполнен не только из HTML-форм (о них
мы подробно поговорим в следующем выпуске), но и любым другим
путем - например, прямой ссылкой, или любым другим способом запроса URL.
Например, в случае графического счетчика посетителей (который
вызывается с веб-страницы через <IMG src="...">) ему можно передать
некоторые параметры прямо в его URL:
Основным же недостатком этого метода является то, что максимальная
длина URL ограничена, соответственно, этим методом можно передать очень
ограниченный объем информации. Конкретное значение максимальной
длины URL зависит как от конкретного веб-сервера, так и от конкретного
броузера. В спецификации HTML 4.0 не рекомендуют применять метод GET,
если общая длина строки параметров может превысить 100 символов.
Другим недостатком является то, что не все символы могут быть переданы
в строке URL.
Параметры вызова методом GET скрипт получает из переменной среды
QUERY_STRING.
Метод "POST"
В отличие от метода GET, метод POST специально служит для отправки данных
на серверные приложения. При вызове скрипта методом POST параметры передаются
скрипту не как часть URL, а в теле HTTP-запроса (скрипт их получает на
стандартный ввод).
Соответственно, общая длина параметров не имеет таких жестких ограничений
и может составлять десятки килобайт.
При вызове скрипта методом GET эта переменная имеет значение 'GET',
при вызове методом POST - 'POST'. К слову, эта переменная может принимать
и другие значения - если вызов скрипта вставляется в страницу
с помощью SSI, то переменная REQUEST_METHOD имеет значение 'INCLUDE'.
А теперь напишем простой скрипт, который принимает переданные
ему параметры и выдает их в броузер. Для начала он будет принимать
параметры, переданные методом GET.
Теперь сохраните этот скрипт на веб-сервере в cgi-папке под именем,
скажем, test.cgi. Допустим, он доступен на веб-сервере по URL
http://host/cgi-bin/test.cgi
Если все сделано правильно, то, запросив в браузере этот URL,
Вы получите ответ:
"Строка запроса: ".
После двоеточия ничего
не будет, т.к. никакие параметры мы пока не передавали.
Теперь попробуйте передать скрипту последовательность символов
в URL после знака '?', скажем:
http://host/cgi-bin/test.cgi?12345abcde
В ответ Вы должны получить
Строка запроса: 12345abcde
т.е. ту последовательность символов, которую Вы указали в URL
после знака вопроса.
Чаще всего параметры передаются в виде строки следующего формата:
name1=value1&name2=value2&name3=value3 ...
т.е. имя параметра отделяется от значения знаком '=', а параметры
разделяются между собой знаком '&'.
Именно такую строку параметров формирует броузер при отправке
содержимого HTML-формы. Это - "общепринятый" формат строки запроса.
Разбор (parsing) параметров
Для того, чтобы скрипт мог использовать в своей работе переданные ему
параметры, он должен "выделить" их из переданной строки параметров
(она же - "строка запроса") -
иначе говоря, произвести "разбор" (parsing) строки параметров.
В CGI-скриптах на Perl для этого удобно использовать функцию split,
которая умеет разбивать строку на части, и возвращать эти части
в виде массива:
@parts=split(delimiter, string);
Здесь string - это исходная разбиваемая строка, delimiter - разделитель
(последовательность символов, которая разделяет в исходной строке
искомые части).
Вообще, это очень удобная функция для работы с "текстовой"
базой данных и многих других вещей.
Скажем, в таком фрагменте:
$s="aaa::bbb::ccc";
d=split("::",$s);
функция split вернет массив с элементами "aaa","bbb","ccc".
Теперь вернемся к нашему конкретному случаю - разбору параметров
из переданной скрипту строки. Как видно из ее формата (см. выше),
разбор делится на два этапа:
Выделение параметров из строки запроса
Выделение имени и значения каждого параметра
В первом случае разделителем будет символ '&', во втором - символ '='.
Этот фрагмент "разбирает" строку запроса и формирует хэш %PARAM
с переданными параметрами.
Подобный код (возможно, чуть более сложный) будет используется
практически в каждом CGI-скрипте - а именно в тех скриптах,
которые принимают параметры.
Прием параметров, переданных методом
POST, отличается незначительно: как я писал выше, при использовании
этого метода параметры передаются не в переменной среды, а на
"стандартный ввод" скрипта, т.е. методы передачи отличаются источником.
Таким образом, строку $s=$ENV{'QUERY_STRING'};
адо заменить на строку $s=<STDIN>;
В ряде случаев желательно, чтобы скрипт "умел" принимать данные
обоими способами. Это несложно - ведь скрипту передается метод
его запроса; он может его анализировать и поступать двояко:
$m=$ENV{'REQUEST_METHOD'};
#Если метод - POST, то получаем параметры со станартного ввода,
#Иначе - из переменных среды
if ($m eq 'POST')
{$s=<STDIN>}
else {$s=$ENV{'QUERY_STRING'};};
Вот и все на сегодня. В следующем выпуске мы подробно рассмотрим веб-формы - мощное средство
языка HTML, позволяющее создавать на веб-страницах "пользовательский
интерфейс" к скриптам, и таким образом давать пользователю возможность
задавать скрипту параметры запроса в удобной, "человеческой" форме.