Метод доступа GET
Метод доступа GET долгое время был основным методом доступа из форм к CGI-скриптам. Это происходило по причине отсутствия при вводе большого количества данных и из-за прямого обращения к скриптам по их URL. В настоящее время ситуация меняется, но тем не менее данный метод занимает едва ли не главное место в программировании обработки данных из HTML-форм.
Условно использование GET можно разбить на два способа:
- запросы типа isindex;
- запросы типа from-urlencoded.
В первом случае имитируется или реально происходит передача запроса, который появляется при вводе данных в строке приглашения контейнера ISINDEX. Во втором случае происходит передача пар "имя_поля-значение". И в том, и в другом случае данные, не входящие в кодировку Latin1, преобразуются в пары шестнадцатеричных символов, предваряемых символом "%" (%20 — пробел).
Кроме вызова скрипта непосредственно из гипертекстовой ссылки, скрипт можно запустить и через Server Site Include. В этом случае данные из формы будут приписываться к URL документа, а не скрипта. Скрипт при этом будет вызываться сервером при разборе текста HTML-страницы перед отправкой ее клиенту.
Кроме собственно запроса, который в методе GET появляется в URL после символа "?", скрипту еще можно передать информацию в HTTP-пути. Это переменная окружения PATH_INFO. Обработка данных из этой переменной требует особого подхода к их получению и использованию в скрипте и гипертекстовых ссылках.
Запрос isindex
Запрос типа isindex является исторически первым способом передачи данных от браузера серверу. Он был разработан для передачи списка ключевых слов для поисковой машины. Запрос данного типа появляется либо в случае использования контейнера ISINDEX, либо при прямом обращении к скрипту через гипертекстовую ссылку. Данный тип запроса имеет ряд особенностей, которые отличают его от запроса типа form-urlencoded.
При использовании контейнера ISINDEX в начале документа появляется шаблон ввода ключевых слов. После ввода списка слов, разделенных пробелом, вызывается скрипт, который принимает список, разбирает его на отдельные слова и выполняет необходимую обработку. Первоначально isindex был ориентирован на модуль, подключавший поисковую систему WAIS к серверу CERN. После появления спецификации CGI стало возможным передавать списки слов любому CGI-скрипту. Запрос типа isindex определен только для метода доступа GET.
Согласно спецификации CGI для метода GET запрос присоединяется к URL документа или скрипта (указан атрибут ACTION в контейнере ISINDEX) после символа "?"(getis2.htm):
http://localhost/htdocs/isindex.htm?search+engine+world+wide+web
или
http://localhost/htdocs/isindex.cgi?search+engine+world+wide+web
Как видно из этого примера, в запросе пробел заменяется на символ "+". Причем буквы русского алфавита в таком запросе перекодировать не надо, они передаются как есть. Если пользователь работает с локализованной версией операционной среды, то все будет отображаться так, как положено. В случае нелокализованной версии операционной среды, например, Windows NT, буквы будут отображаться абракадаброй, но в скрипт будут передаваться правильные коды.
Традиционно в GET данные запроса выбираются из переменной окружения QUERY_STRING. Например, это можно сделать на Perl следующим образом:
#!/usr/local/bin/perl
print "Content-type: text/playn\n\n";
print "Запрос: $ENV{QUERY_STRING}.\n";
В данном примере первый оператор печати формирует заголовок HTTP-сообщения в соответствии со спецификацией CGI. Второй оператор печати распечатывает содержание переменной окружения QUERY_STRING.
Главное при этом — разделить запрос на отдельные слова, чтобы можно было использовать их в качестве ключей поиска. В Perl для этого существует функция split:
#!/usr/local/bin/perl
print "Content-type: text/playn\n\n";
print "Запрос: $ENV{QUERY_STRING}.\n";
@words = split('+',$ENV{QUERY_STRING});
foreach $word (@words)
{
print $word,"\n";
}
В данном случае следует обратить внимание на то, что в запросе нет никаких имен полей — только введенные слова и их разделители. Естественно, если среди введенных символов встретится разделитель, он будет заменен шестнадцатеричным.
У запроса isindex есть еще одно замечательное свойство — это передача данных в командной строке CGI-скрипта. Очевидно, что ввести аргументы пользователь не в состоянии (у него нет удаленного терминала), но вот принять данные из командной строки скрипт может:
#!/usr/local/bin/perl
print "Content-type: text/playn\n\n";
print "Запрос: $ENV{QUERY_STRING}.\n";
$n = @ARGV;
for ($i=0;$i
{
print $ARGV[$i],"\n";
}
Внешне результаты работы данного скрипта и скрипта разбора QUERY_STRING ничем не отличаются. Но данные они получают из разных источников (getis6.htm).
Запрос типа isindex не порождается событием onSubmit, как это происходит в запросах form-urlencoded. Он является одной из разновидностей схемы http универсального локатора ресурсов (URL). При использовании обычной контекстной гипертекстовой ссылки (контейнер A (anchor)) запрос просто дописывается вслед за символом "?".
При программировании на JavaScript обратиться к скрипту через запрос isindex можно либо путем изменения значения атрибута HREF в одном из элементов массива гипертекстовых ссылок документа, либо путем вызова метода replace() объекта Location.
Запрос from-urlencoded
В методе GET запрос типа form-urlencoded является основной формой запроса. От запроса типа isindex он отличается форматом и способом передачи, точнее, кодировкой данных в теле HTTP-сообщения. Данные формы попадают в запрос, который расширяет URL скрипта в виде пар "имя_поля=значение&имя_поля=значение&...". Например, для формы вида:
<FORM ACTION=test.cgi METHOD=get>
Поле1:<INPUT NAME=f1 VALUE=value1>
Поле2:<INPUT NAME=f1 VALUE=value1>
<INPUT TYPE=submit VALUE="Послать">
</FORM>
запрос в сообщении HTTP-протокола будет выглядеть следующим образом:
GET /test.cgi?f1=value1&f2=value2 HTTP/1.0
Несмотря на то, что в форме имеется три поля, переданы будут значения только двух полей. Это связано с тем, что у третьего поля в форме нет имени. Если у поля нет имени, то его значение не передается серверу. Это правило общее для всех полей. Чаще всего оно применяется для полей подтипов submit и reset типа text.
Применение неименованных полей позволяет передавать в скрипт только ту информацию, которая реально требуется для выполнения обработки данных. Иногда неименованные поля применяют и при программировании на JavaScript.
Кроме формата в запросе типа form-urlencoded, данные, введенные в форму, подвергаются дополнительной обработке — кодированию.
Кодирование, собственно, и дало название методу (urlencoded). Согласно спецификации, текстовое сообщение не может содержать символы, не входящие в набор Latin1. Это означает, что вторая половина таблицы ASCII и первые 20 символов должны быть закодированы. В CGI символ кодируется как две шестнадцатеричные цифры, следующие за знаком "%". Для российских Web-узлов это означает, что скрипт, который принимает запрос, должен предварительно перекодировать все шестнадцатеричные эквиваленты в символы (getform2.htm). На Perl это можно реализовать в одну строку:
query =~ s/%(.{2})/pack('c',hex($1))/ge;
В данном случае мы осуществляем глобальную подстановку (оператор "=~ s///"), который употреблен с модификаторами "ge". Первый модификатор обозначает глобальную замену по всей строке query, а второй требует выполнения перед заменой выражения "pack('c',hex($1))". Более подробно о программировании на Perl см. раздел "Введение в программирование на Perl".
Передача параметров через PATH_INFO
Передача данных в скрипты возможна не только при помощи переменной окружения QUERY_STRING или аргументов командной строки скрипта. Передать параметры в скрипт можно через переменную окружения PATH_INFO. Данная переменная принимает свое значение после преобразования URL скрипта. Рассмотрим следующий URL:
http://localhost/cgi-bin/test/arg1/arg2/arg3?param1+param2
Согласно спецификации URI адрес ресурса делится на две части: название схемы адресации и путь к ресурсу:
схема |
разделитель |
путь к ресурсу |
http |
: |
//localhost/cgi-bin/test/arg1/arg2/arg3?param1+param2 |
Схема адресации задается протоколом обмена данными. Обращение к скрипту осуществляется по схеме http. В свою очередь, в схеме http путь снова делится на две части: адрес ресурса и параметры. Эти части разделены символом "?". Параметры могут быть записаны либо в форме isindex, либо в формате form-urlencoded:
адрес ресурса |
разделитель |
параметры |
//localhost/cgi-bin/test/arg1/arg2/arg3 |
? |
param1+param2 |
Адрес ресурса в случае обращения к скрипту снова можно разделить на две части — адрес скрипта и путевой параметр PATH_INFO:
адрес скрипта |
PATH_INFO |
//localhost/cgi-bin/test |
/arg1/arg2/arg3 |
В данном случае явного разделителя между адресом скрипта и PATH_INFO нет. Деление определяется настройками сервера. У большинства серверов стандартным каталогом CGI-скриптов является каталог cgi-bin. При этом подразумевается, что все файлы этого каталога — скрипты. Можно даже указать файл с расширением html, который в данном случае будет интерпретироваться как скрипт (getpath1.htm). Значение путевого параметра сервер помещает в переменную окружения PATH_INFO. При этом в нее попадает и лидирующий символ "/".
Управление работой скрипта через путевой параметр довольно популярно. Например, при выполнении перенаправления, когда нужно собирать статистику обращений к ресурсам, расположенным вне Web-узла:
http://localhost/cgi-bin/banner/http://otherhost/page.html
Вообще говоря, при таких перенаправлениях возникает опасность Web-спуффинга. Существует очень большая вероятность, что администратор не заметит подмены одной из частей такого URL.
PATH_INFO применяется не только в совокупности с каталогами скриптов, но и с любым скриптом, определенным пользователем. Часто в качестве такого скрипта определяются файлы с расширением *.cgi:
http://www.intuit.ru/~user/script.cgi/path_param/test?arg1+arg2
В этом примере в переменную PATH_INFO попадет /path+param/test.
|