Технология CGI - Common Gateway Interface. Этапы создания веб-приложения

1) Общие сведения о CGI
С 1993 года CGI является очень часто используемой технологией создания трехзвенных клиент/серверных приложений в Интернет. CGI-приложение совместно с Web-сервером выполняют роль сервера приложений в трехзвенной архитектура клиент/сервер. CGI – набор правил (спецификация), согласно которым пользовательские программы, запускаемые на Web-сервера, могут возвращать данные клиенту в виду HTML-документа. CGI – это консольное приложение, загружаемое в ответ на запрос клиента на выборку или обновление данных, функционирующее как отдельный однопоточный процесс под управлением Web-сервера и выгружаемое сразу после завершения работы. WinCGI – Windows реализация CGI.

2) Варианты реализации
Программа, запускаемая Web-сервером в соответствии со спецификацией CGI, называется CGI-скриптом. Она может быть написана на любом языке программирование (С, Basic, Pascal и т.п.) или на командной языке (языки shell, perl и т.п.), допускающем создание исполняемых модулей. CGI-скрипт исполняет роль посредника между Web-сервером и другими серверами, например, сервером БД, и поэтому часто называется шлюзом. CGI-программы по умолчанию размещаются в каталоге C:\InetPub\Scripts|Cgi-bin, но можно создавать и свой виртуальный каталог.

3) Способы взаимодействия CGI и WEB-сервера
В спецификации CGI предусмотрено несколько способов взаимодействия CGI-программы и Web-сервера, отличающиеся вариантом обмена данными между сервером и программой.
. Передача параметров в командной строке (например, с помощью дескриптором ISINDEX, помещаемого в раздел HTML-документа, или FORM-URLENCODED).
. Передача значений переменных окружения (их более 17 штук).
. Передача данных через стандартный входной поток (STDIN, STDOUT).

Запрос типа ISINDEX – это запрос вида: http://site.ru/somthig-cgi/cgi-script?слово1+слово2+слово3
Главным здесь является список слов после символа «?». Слова перечисляются через символ «+» и для кириллицы не кодируются в шестнадцатеричные последовательности. Последовательность слов после символа «?» будет размещена в переменной окружения QUERY_STRING.

Запрос типа FORM-URLENCODED – это запрос вида: http://site.ru/something-cgi/cgi-script?field=word1&field2=word2
Данные формы записываются в виде пар «имя_поля-значение», которые разделены символом «&».

Переменные окружения, которые не зависят от типа запроса:
SERVER_SOFTWARE – показывает название и версию http-сервера в формате: название/версия.
SERVER_NAME – показывает доменное имя сервера.
SERVER_ADDR – показывает IP сервера.
SERVER_ADMIN – e-mail администратора web-сервера.
GATEWAY_INTERFACE – версия CGI на момент компиляции httpd демона в формате: CGI/версия
DATE_GMT – текущая дата и время во временной зоне GMT.
DATE_LOCAL – текущие дата и врем во временной зоне сервера.
DOCUMENT_ROOT – путь к главному каталогу web-сервера.
Переменные окружения, которые зависят от типа запроса:
SERVER_PROTOCOL – протокол, по которому был получен запрос.
SERVER_PORT – порт, на который был получен запрос.
REQUEST_METHOD – тип запроса: POST, GET и так далее.
REQUEST_URL – страница, отправившая запрос.
SCRIPT_NAME – URL скрипта без имени сервера.
SCRIPT_FILENAME – полное имя файла скрипта на диске.
QUERY_STRING – информация, содержащаяся в командной строке вызова скрипта (после? в URL’е).
CONTENT_TYPE – MIME-тип данных, передаваемых скрипту.
CONTENE_LENGTH – длина передаваемых данных.

Поток стандартного вывода:

Ввод данных в скрипт через поток стандартного ввода осуществляется только при использовании метода доступа к ресурсу (к скрипту) POST. При этом в переменную окружения CONTENT_LENGTH помещается число символов, которое необходимо считать из потока стандартного ввода скрипта, а в переменную окружения CONTENT_TYPE помещается тип кодирования данных, которые считывают из потока стандартного ввода. При посимвольном считывании в С можно применить, например, такой фрагмент кода:

int n;
char *buf;
n=atoi(getenv(*CONTENT_LENGTH*));
buf=(char *)malloc(n+1);
memset(buf, ‘\000’,n+1);
for (i=0; iBR> {buf[i]=getchar()}

free(buf);

4) Методы передачи данных
a) Метод GET выполняет передачу данных CGI-программе через переменные окружения (среды), которые фактически добавляются к URL через разделительный знак?.

Прежде всего, для этих целей используется переменная query_string – длинная строка, состоящая из пар имя = значение, отделяемых друг от друга символом амперсанда — &. Получается быстро, однако объем передаваемых данных не превышает 256?1024 байт в зависимости от типа Web-сервера.

b) Метод POST выполняет передачу данных через стандартный поток ввода stdin (Ini-файл для WinCGI). Фактически данные добавляются к телу HTML-запроса. Количество передаваемых байт указывается в переменной среды content_length. Это более медленный способ передачи данных, но объем передаваемых данных не ограничен.

c) Параметр HREF тэга A
Помимо методов GET и POST тэга

, можно вызвать CGI-программу через параметр HREF тэга ссылки . Параметры передаются после имени файла за знаком?.

Передача данных аналогична использованию метода GET.

5) Диаграмма последовательностей


Действие 1 : Пользователь просматривает HTML-документ и встречает ссылку на страницу, содержащую форму (используется тэг ), предназначенную, например, для запроса к БД. Пользователь вводит в полях ввода на форме требуемые данные и нажимает на кнопку SUBMIT (отправить) или графическую кнопку IMAGE. HTML-тэг имеет два обязательных атрибута: METHOD и ACTION. Атрибут ACTION определяет URL, в качестве которого должно быть имя CGI-программы, обычно размещаемой в каталоге. Атрибут METHOD, обычно принимающий значение GET или POST, определяет механизм передачи данных серверу.

Действие 2 : Web-браузер собирает введенные на форме данные, определяет способ передачи данных в зависимости от указанного метода (GET или POST) и передает вызов Web-серверу.

Действие 3 : Web-сервер получает вызов через сокетное соединение. Сервер разбирает сообщение на части и определяет, что это метод POST или GET. Далее запускается CGI-взаимодействие.

Действие 4 : Web-сервер задает переменны окружения (в ОС MS-DOS они задаются командой Set). Переменные окружения (environment variable) играют роль доски объявлений при обмене данными между Web-сервером и CGI-программой. Обычно используют следующие переменные: server_name, request_method, path_info, script_name, content_type, content_length и ряд других. Когда CGI-программа вызывается посредством формы (наиболее распространенный вариант), браузер передает серверу длинную строку, в начале которой указан полный путь до CGI-программы. Далее следуют другие данные, называемые данными пути, и передаются CGI-программе через переменную окружения path_info: http://myserver/cgi-bin/mycgi.exe/showrecord?recNo=20 где: showrecord? – данные пути, recNo=20 – строка запроса.

Действие 5 : Web-сервер запускает CGI-программу, располагаемую по умолчанию в каталоге C:\InetPub\scripts|cgi-bin. Однако можно создавать и свои виртуальные каталоги.

Действие 6 : CGI-программа анализирует переменные окружения и определяет, что отвечает на POST. В языке С доступ к переменным окружения получают с помощью функции getenv().

Действие 7 : CGI-программа получает тело сообщения через стандартный поток ввода (stdin). Переменная окружения content_length сообщает, сколько данных находится в сообщении. В языке С можно воспользоваться функциями fread или scanf для чтения данных из потока.

Действие 8 : CGI-программа выполняет некоторые действия, например, запрос к БД.

Действие 9 : CGI-программа вне зависимости от метода GET или POST возвращает результат всегда через стандартный поток выхода (stdout). В языке С используются функции printf или fwrite.

Действие 10 : Web-сервер возвращает результат Web-браузеру.

6) Особенности доступа
. Доступ к БД из CGI может быть выполнен с помощью программного интерфейса ODBC или объектных интерфейсов OLE DB или ADO. В Delphi используется BDE.
. Безопасность доступа обеспечивается использованием протоколов SSL (Secure Sockets Layer), S-HTTP (Secure HTTP), брандмауэров.
. Для обеспечения большей интерактивности CGI-программы на некоторых Web-серверах можно применять файлы magic cookies или просто cookies, обозначающие серверные данные, сохраненные на клиенте.
. Некоторые серверы могут производить синтаксический анализ отправляемого браузеру HTML-документа и предоставляют набор команд для вставки внутрь комментариев: текущий даты, времени, сведения о последнем изменении документа и ряд других. Это называется серверной вставкой SSI – Server-Side Include.

7) Достоинства CGI

Языковая независимость, заключающаяся в возможности написания CGI-программ на любом языке программирования или командном языке. Так командный язык Perl обеспечивает кроссплатформенность CGI (PCGI).
. Процессорная независимость, заключающаяся в том, что при запуске CGI-программы порождается отдельный от Web-сервера процесс и в случае ошибки она не может «сломать» Web-сервер.
. Открытость стандарта.
. Архитектурная независимость от реализации сервера, т.е. его можно использовать на любом сервере.
. Прозрачность использования.

8) Недостатки CGI

Большие временные затраты, обусловленные запуском отдельного однопоточного процесса для каждого клиентского запроса, заканчивающегося по его окончании. Это приводит к невысокому быстродействию. Есть разработка FastCGI, но она не очень широко поддерживается.
. Трудно «вести» БД, поскольку для каждого запроса запускается отдельный процесс, т.е. требуется новое подключение.
. CGI ограничен по способности функционирования, поскольку спецификация предусматривает только простую ответную роль программы при генерации результата на запрос пользователя.
. CGI неудобен тем, что жестко привязан к Web-страницам.

9) Создание CGI в Delphi
. Подход Delphi для создания CGI
CGI и WinCGI-приложения в Delphi относятся к классу TCGIApplication. Генерируемый мастером код приложений CGI и WinCGI практически одинаков и отличаются только строкой директивы компилятора: {$APPTYPE CONSOLE|GUI}. Для создания CGI-приложения следует из главного меню Delphi 5-7 выполнить команды: File\New.

В открывшемся многостраничном окне New Items репозитория объектов Delphi следует выбрать страницу Business и активизировать пиктограмму DB Web Application Wizard. Далее отвечать на вопросы.

Структурная схема модуля CGI на Delphi


. Обзор принципов реализации CGI на Delphi
WebDispatcher с помощью объекта WebRequest анализирует поступающие запросы и выбирает нужный объект Action, который передает запрос на сервер БД. Соответствующий Producer является генератором контента HTML-кода, который переправляется через объект WebResponse на Web-сервер и далее клиенту. В объектах Producer доступны тэги вида <# …..>, позволяющие взаимодействовать коду на Pascal и коду на HTML. Для Web-браузера эти тэги не имеют смысла, однако помогают подставлять данные из БД внутрь страниц на HTML.

. Пример программы CGI

Program MyCGI;
{$APPTYPE CONSOLE} // {$APPTYPE GUI} – для WinCGI
Uses Webbroker, HTTPApp, CGIApp, Unit1 In ‘Unit1.Pas’ {WebVodule1: TWebModule}
{$R*.RES}
Begin
Application.Initialize;
Application.CreateForm(TWebModule1: WebModule1);
Application.Run;
End.

-Length: 22

name=Vasya&okbutton=OK

При использовании метода POST данные формы отправляются уже после "двух Enter -ов" - в теле запроса. Все, что выше - на самом деле заголовок запроса (и когда мы использовали метод GET , данные формы отправлялись в заголовке).

Для того, чтобы сервер знал, на каком байте закончить чтение тела запроса, в заголовке присутствует строка Content-Length ; о том же, что данные формы будут переданы виде параметр1=значение1&параметр2=значение2..., причем значения передаются в виде urlencode - то есть, точно так же, как и с помощью метода GET , но в теле запроса, - серверу сообщает заголовок "Content-Type: application/x-www-form-urlencoded" .

О том, что такое urlencode - чуть ниже.

Преимущество метода POST: отсутствие ограничения на длину строки с данными формы.

При использовании метода POST невозможно отправить форму, просто "зайдя по ссылке", как было с GET .

Для краткости изложения, введем термины "GET-форма" и "POST-форма", где префикс соответствует значению атрибута method тэга

.

При использовании POST -формы, в ее атрибуте action можно указать после знака вопроса и параметры GET -формы. Таким образом, метод POST включает в себя и метод GET .

Технология CGI

Мы разобрались, как создать HTML -форму, и как браузер отправляет введенные в нее данные на сервер. Но пока не понятно, что будет сервер делать с этими данными.

Сам по себе web-сервер умеет только отдавать запрошенную страницу, и ничего более того, и ему все переданные данные формы, в общем-то, совершенно безразличны. Для того, чтобы можно было обработать эти данные с помощью какой-либо программы и динамически сформировать ответ браузеру, и была изобретена технология CGI (Common Gateway Interface).

Взглянем на этот URL: http://www.example.com/cgi-bin/form_handler.cgi . Первое предположение, которое можно сделать на его счет, обычно такое: сервер отдает содержимое файла form_handler.cgi из каталога cgi-bin . Однако, в случае с технологией CGI дело обстоит по-другому. Сервер запускает программу form_handler.cgi и передает ей данные формы. Программа же формирует текст, который передается браузеру в качестве ответа на запрос.

Программу form_handler.cgi можно написать на любом языке программирования, главное - соблюдать в программе стандарт CGI . Можно использовать, например, популярный скриптовый язык Perl. А можно написать все на Си, или на shell-скриптах... Для примера, напишем эту программу на Си. Но сначала разберемся, как происходит обмен данными между web-сервером и CGI -программой:

1. Перед запуском CGI-программы, сервер устанавливает переменные окружения (Вам они наверняка знакомы по команде PATH). В каждый мало-мальски серьезном языке программирования есть средства для чтения переменных окружения. Стандарт CGI определяет весьма значительный набор переменных, которые должны быть определены перед запуском CGI-программы. Рассмотрим сейчас только три из них:

REQUEST_METHOD - метод передачи данных - GET или POST (есть и другие, но пока мы их не рассматриваем)

QUERY_STRING - содержит часть URL после вопросительного знака, или, другими словами, данные GET -формы.

CONTENT_LENGTH - длина тела запроса (данные POST -формы).

2. Сервер запускает CGI -программу. Тело запроса передается программе в виде стандартного ввода (stdin ) - будто бы эти данные были введены с клавиатуры.

3. Программа выдает ответ браузера на стандартный вывод (stdout ) - "на экран" . Этот вывод перехватывается веб-сервером и передается браузеру.

Это CGI -программа на Си , выводящая содержимое полученных от web-сервера параметров форм:

1. #include

2. #include

4. int main(void)

6. // Читаем переменные среды, установленные веб-сервером

7. char *query_string = getenv("QUERY_STRING");

8. char *request_method = getenv("REQUEST_METHOD");

10. char *post_data; // Буфер для данных POST-запроса

11. int post_length = 0; // Длина тела запроса

13. if (strcmp(request_method, "POST") == 0) {// Если получен POST-запрос,

14. post_length = atoi(getenv("CONTENT_LENGTH")); // сначала читаем из

15. // переменной среды его длину,

16. if (post_length) {// если она не нулевая,

17. post_data = (char*)malloc(post_length+1); // выделяем память для буфера,

18. fread(post_data, post_length, 1, stdin); // читаем со стандартного ввода тело запроса,

19. post_data = 0; // завершаем строку нулевым байтом.

23. // Выводим заголовок ответа...

Благодаря Всемирной паутине, почти любой может дать информацию в Интернете в приятном для глаз и пригодном для широкого распространения виде. Вы несомненно путешествовали по Интернету и видели другие сайты, и теперь вероятно знаете, что пугающие сокращения типа "HTTP" и "HTML" - просто своеобразные сокращения для "Веб" и "способ выражения информацим в Интернете". Возможно у Вас уже есть некоторый опыт представления информации в Интернете.

Интернет доказал, что является идеальной средой для распределения информации, как видно по его огромной популярности и масштабного развития. Хотя кое-кто подвергает сомнению полезность Интернета и приписывают ее широкое развитие и популярность главным образом навязчивой рекламе, Интернет бесспорно является важным средством представления всевозможных видов информации. Мало того, что существует множество услуг по предоставлению самой свежей информации (новости, погода, спортивные события в реальном времени) и материалов справочного характера в электронном виде, предлагаются также значительные объемы данных другого рода. Налоговое управление США, которое распространило все свои бланки налоговых деклараций в 1995 году и другую информацию через Всемирную паутину, недавно призналось о получении писем от поклонников своего Веб-сайта. Кто бы мог подумать, что Налоговое управление когда-нибудь будет получать письма от поклонников? Это произошло не от того, что его сайт был хорошо оформлен, а потому что он оказался по-настоящему полезным инструментом для тысяч, а возможно и миллионов людей.

Что делает Веб уникальным и таким привлекательным информационным сервисом? Прежде всего тем, что он предоставляет интерфейс гиперсреды для данных. Вспомните дисковод жесткого диска своего компьютера. Как правило, данные выражаются в линейном виде, аналогично файловой системе. Например, Вы имеете ряд папок, а внутри каждой папки находятся либо документы либо другие папки. Веб использует разную парадигму для выражения информации называемой гиперсредой. Гипертекстовый интерфейс состоит из документа и связей. Связи - это слова, на которые кликают, чтобы увидеть другие документы или отыскать другие виды информации. Веб расширяет концепцию гипертекста, включив другие типы носителей, например графику, звуки, видео (отсюда имя "гиперсреда"). Выделение текста или графики на документе позволяет увидеть связанную информацию о выделенном элементе в любом количестве форм.

Почти каждый человек может извлечь выгоду из этого простого и уникального способа представления и распределения информации, начиная от академиков, которые хотят немедленно использовать данные вместе со своими коллегами, и кончая деловыми людьми, которые дают информацию о своей компании всем желающим. Однако, хотя дать информацию чрезвычайно важно, в последние несколько лет многие ощутили, что не менее важным процессом является получение информации.

Хотя Веб предоставляет для информации уникальный интерфейс гиперсреды, имеется много других эффективных способов распределения данных. Например, сетевые услуги типа Протокола передачи файлов (FTP) и группа новостей "Gopher" существовали намного раньше появления Всемирной паутины. Электронная почта была первичной средой для связи и обмена информацией по Интернету и большинством других сетей почти с самого начала функционирования этих сетей. Почему Интернет стал таким популярным способом распределения информации? Мультимедийный аспект Интернета внес ощутимый вклад в его небывалый успех, но для того, чтобы Интернет стал наиболее эффективным он должен быть интерактивным.

Без способности получать ввод от пользователей и давать информацию, Веб был бы полностью статической средой. Информация была бы доступна только в формате, определенном автором. Это подорвало бы одну из вычислительных возможностей вообще: интерактивную информацию. Например, вместо того, чтобы принуждать пользователя к просмотру нескольких документов, как если бы он или она просматривали книгу или словарь, будет лучше позволить пользователю определить ключевые слова по интересующей их тематике. Пользователи могут настраивать представление данных, а не полагаться на жесткую структуру, определенную поставщиком содержимого.

Термин "сервер Веб" может ввести в заблуждение, потому что он может относиться и к физической машине и программному обеспечению, используемому в ней для взаимодействия с Интернет-браузерами. Когда браузер запрашивает заданный адрес Веб, он сначала подключается к машине через Интернет, посылая программному обеспечению Веб-сервера запрос о документе. Это программное обеспечение работает непрерывно, ожидая поступления таких запросов и отвечая соответствующим образом.

Хотя серверы могут посылать и получать данные, у самого сервера функциональные возможности ограничены. Например, наиболее примитивный сервер может только отослать требуемый файл на браузер. Сервер обычно не знает, что делать с тем или иным дополнительным вводом. Если Интернет-провайдер не сообщает серверу, как обработать такую дополнительную информацию, вероятнее всего сервер проигнорирует ввод.

Для того, чтобы сервер смог выполнять и другие операции, помимо поиска и пересылки файлов на Интернет-браузер, нужно знать, как расширить функциональные возможности сервера. Например, сервер Веб не может производить поиск в базе данных, на основе ключевого слова, введенного пользователем, и возвращать несколько документов соответствия, если такая способность не была каким-то образом запрограммирована для сервера.

Что такое CGI?

Общешлюзовой интерфейс (CGI) является интерфейсом к серверу, который позволяет расширить функциональные возможности сервера. Используя CGI, можно работать в диалоговом режиме с пользователями, которые обращаются к вашему сайту. На теоретическом уровне, CGI позволяет расширить возможности сервера в отношении анализа (интерпретации) ввода, поступающего от браузера, и возвращать информацию, основанную на введенной информации пользователя. На практическом уровне, CGI - это интерфейс, позволяющий программисту записать программы, которые легко связываются с сервером.

Обычно, для расширения возможностей сервера, Вам пришлось бы самому модифицировать сервер. Такое решение нежелательно, потому что это требует понимания нижнего уровня сетевого программирования по протоколу Интернета. Это также требовало бы редактирования и перекомпиляции исходного кода сервера или записи пользовательского сервера для каждой задачи. Допустим, нужно расширить возможности сервера так, чтобы он действовал как шлюз Web-to-e-mail (от Веб к эл.почте), отбирая информацию, введенную пользователем, из браузера и посылая ее по электронной почте другому пользователю. В сервер пришлось бы вставить код для анализа ввода от браузера, пересылки бы его по электронной почте другому пользователю, и пересылке ответа назад в браузер через сетевое соединение.

Во-первых, такая задача требует наличия доступа к коду сервера, что не всегда возможно.

Во-вторых, это трудно и требует обширных технических знаний.

В-третьих, это применимо только для конкретного сервера. Если нужно переместить ваш сервер на другую платформу, придется запустить или по крайней мере потратить много времени, занимаясь переносом кода на эту платформу.

Почему CGI?

CGI предлагает переносимое и простое решение этих проблем. Протокол CGI определяет стандартный способ для программ, чтобы связаться с сервером Веб. Без каких-либо специальных знаний, можно записать программу на любом машинном языке, который сопрягается и связывается с сервером Веб. Эта программа будет работать со всеми серверами Веб, которые понимают протокол CGI.

Связь CGI осуществляется стандартным вводом и выводом, что означает, что, если Вы знаете, как печатать и читать данные, используя свой язык программирования, можно написать приложение сервера Веб. Помимо анализа ввода и вывода, программирование приложений CGI почти эквивалентно программированию любого другого приложения. Например, для программирования программы "Hello, World!", используются функции печати вашего языка и формат, определенный для программ CGI, чтобы напечатать соответствующее сообщение.

Выбор языка програмирования

Поскольку CGI - универсальный интерфейс, Вы не ограничены каким-либо определенным машинным языком. Часто задают важный вопрос: какие языки программирования можно использовать для программирования CGI? Вы можете использовать любой язык, который позволяет делать следующее:

  • Печатать в стандартном выводе
  • Читать со стандартного ввода
  • Читать с переменных режимов

Почти все языки программирования и много языков описания сценария выполняют эти три действия, и можно использовать любой из них.

Языки подпадают под один из следующих двух классов: транслируемый и интерпретируемый. Транслируемый язык -например, C или C++ обычно меньше и быстрее, в то время как интерпретируемые языки, такие как Perl или Rexx, иногда требуют загрузки большого интерпретатора после запуска. Дополнительно, Вы можете распределять двоичные коды (код, транслируемый в машинный язык) без исходного кода, если ваш язык транслируемый. Распределение интерпретируемых сценариев обычно означает распределение исходнго кода.

Перед тем, как выбрать язык, сначала нужно рассмотреть свои приоритеты. Нужно оценить выгоды от скорости и эффективности одного языка программирования с легкостью программирования другого. Если у Вас есть желание изучить другой язык, вместо использования того, который Вы уже знаете, тщательно взвести преимущества и недостатки обоих языков.

Два наиболее часто используемых языка для программирования CGI - это C и Perl (оба из которых рассматриваются в настоящей книге). У обоих имеются четкие преимущества и недостатки. Perl - язык очень высокого уровня, и в то же время мощный язык, особенно пригодный для синтаксического анализа текста. Хотя легкость использования, гибкость, и мощность делает его языком, привлекательным для программирования CGI, его относительно большой размер и более медленная работа иногда делает его неподходящим для некоторых приложений. Программы C меньше по размеру, более эффективны и обеспечивают контроль за системой более низкого уровня, но более сложны для программирования, не имеют легких встроенных подпрограмм обработки текста, и их труднее отладить.

Какой язык является наиболее подходящим для программирования CGI? Тот, который Вы считаете для себя более удобным с точки зрения программирования. Оба одинаково эффективны для программирования приложений CGI, и с надлежащими библиотеками, оба имеют схожие возможности. Однако, если Вы имеете труднодоступный сервер, можно использовать меньшие транслируемые программы C. Если Вы должны быстро написать приложение, которое требует значительной работы по обработке текста, можно вместо него использовать Perl.

Предостережения

Имеются некоторые важные альтернативы к приложениям CGI. Много серверов теперь включают API-программирование, которое облегчает программирование прямых расширений сервера в противоположность отдельным приложениям CGI. Серверы API обычно более эффективны, чем программы CGI. Другие серверы включают встроенные функциональные возможности, которые могут обрабатывать специальные элементы без CGI, например, сопряжение баз данных. И наконец, некоторые приложения могут быть обработаны некоторыми новыми клиентскими (а не серверными) технологиями типа Java. Быстро ли устареет CGI в условиях таких быстрых изменений в технологии,?

Вряд ли. CGI имеет несколько преимуществ перед более новыми технологиями.

  • Он универсален и переносим. Вы можете написать приложение CGI, используя практически любой язык программирования на любой платформе. Некоторые из альтернатив, такие как API сервера, ограничивают Вас некоторыми языками и намного сложны для изучения.
  • Маловероятно что, клиентские технологии типа Java, заменят CGI, потому что имеются некоторые приложения, для которых серверные приложения намного лучше подходят для выполнения.
  • Многие из ограничений CGI - это ограничения HTML или HTTP. По мере развития стандартов Интернета в целом, развиваются и возможности CGI.

Резюме

Общешлюзовой интерфейс - это протокол, в соответствии с которым программы взаимодействуют с серверами Веб. Универсальность CGI дает программистам возможность написать шлюзовые программы почти на любом языке, хотя имеются много компромиссных решений, связанных с различными языками. Без этой способности, создание интерактивных страниц Веб было бы затруднено, в лучшем случае, потребовалась бы модификациия сервера, и интерактивность оказалась бы недоступной для большинства пользователей, которые не являются администраторами сайта.

Глава 2. Основы

Несколько лет назад, я создавал для колледжа в Гарварде страницу, куда бы можно было представлить свои комментарии о них. В то время, Интернет был молод, а документации было мало. Я, подобно многим другим, опирался на краткую документацию и систему программирования, созданную другими, чтобы научиться программированию CGI. Хотя этот метод изучения потребовал определенного поиска, множества экспериментов, и создавал много вопросов, он был очень эффективным. Настоящая глава - плод моей работы с CGI на ранних этапах (с несколькими уточнениями, разумеется).

Хотя для того, чтобы, полностью понять общешлюзовой интерфейс и достичь мастерства при работе с ним требуется некоторое время, сам протокол довольно прост. Любой человек, у которого есть некоторые основные навыки программирования, и который знаком с Веб, может быстро научиться программированию довольно сложных приложений CGI так же как я и другие научились этому несколько лет назад.

Цель этой главы состоит в том, чтобы представить основы CGI в комплексном, хотя и сжатом виде. Каждая концепция, рассматриваемая здесь, подробно представлена в последующих главах. Однако, после изучения этой главы, можно сразу же начать программирование приложений CGI. Как только Вы достигнете этого уровня, можно изучить тонкости CGI, либо прочитав остальную часть этой книги, либо просто экспериментируя самостоятельно.

Вы можете свести программирование CGI к двум задачам: к получению информации от браузера Веб и отсылке информации назад на браузер. Это делается достаточно интуитивно, как только Вы усвоите обычное использование приложений CGI. Часто пользователю предлагают заполнить какую-либо форму, например, вставить свое имя. Как только пользователь заполняет форму и нажимает Enter, эта информация посылается программе CGI. Программа CGI должна затем преобразовать эту информацию в то, что она понимает, соответственно обработать ее, и затем послать назад браузеру, будь то простое подтверждение или результат поиска в многоцелевой базе данных.

Другими словами, для программирования CGI требуется понять, как получить ввод от Интернет-браузера и как отослать вывод назад. Что происходит между стадиями ввода и вывода программы CGI, зависит от цели разработчика. Вы обнаружете, что главная сложность программирования CGI заключается в этой промежуточной стадии; после того, как Вы узнаете, как работать с вводом и выводом, этого будет, по существу, достасточно, чтобы стать разработчиком CGI.

В настоящей Главе, Вы изучите принципы, лежащие в основе ввода и вывода CGI, а также другие элементарные навыки, которые потребуются, чтобы записывать и использовать CGI, включая такие моменты, как создание форм HTML и присвоение имени вашим программам CGI. В данной главе рассматриваются следующие темы:

  • Традиционная программа " Hello, World!";
  • Вывод CGI: отсылка информации назад для отображения в Интернет-браузере;
  • Конфигурирование, установка, и выполнение приложения. Вы узнаете о различных платформах и серверах Веб;
  • Ввод CGI: интерпретация информации, посланной браузером Веб. Ознакомление с некоторыми полезными библиотеками программирования для анализа такого ввода;
  • Простой пример: он охватывает все уроки данной главы;
  • Стратегия программирования.

Из-за характера данной главы, я только слегка касаюсь некоторых тем. Не волнуйтесь; все эти темы рассматриваются гораздо глубже в других главах.

Hello, World!

Вы начинаете с традиционной вводной задачи программирования. Вы напишете программу, которая отобразит "Hello, World!" на вашем браузере Веб. Прежде, чем написать эту программу, Вы должны понять, какую информацию браузер Веб ожидает получить от программ CGI. Вы также должны знать, как выполнить эту программу, так чтобы увидеть ее в действии.

CGI независит от языка, так что Вы можете реализовать эту программу на любом языке. Здесь используется несколько различных языков, чтобы продемонстрировать независимость каждого языка. В языке Perl, программа " Hello,World!" показана в листинге 2.1.

Листинг 2.1. Hello, World! в Perl. #!/usr/local/bin/perl # Hello.cgi - Моя первая программа CGI print "Content-Type: text/html\n\n"; print " \n"; print "Hello, World!"; print "\n"; print "\n"; print "

Hello, World!

\n"; print " \n";

Сохраните эту программу как hello.cgi, и установите ее в соответствующем месте. (Если Вы не уверены, где оно находится, не беспокойтесь; Вы узнаете это в разделе "Установка и выполнение программы CGI " ниже в данной главе.) Для большинства серверов нужный каталог называется cgi-bin. Теперь, вызовите программу из вашего браузера Веб. Для большинства, это означает открыть следующий универсальный указатель ресурса (URL):

http://hostname/directoryname/hello.cgi

Hostname - имя вашего сервера Веб, и directoryname - каталог, в который Вы помещаете hello.cgi (вероятно cgi-bin).

Разбиение hello.cgi

Следует отметить несколько моментов относительно hello.cgi.

Во-первых, вы используете простые команды печати. Программы CGI не требуют никаких специальных дескрипторов файла или описателей вывода. Чтобы послать вывод браузеру, просто печатают на stdout.

Во-вторых, обратите внимание на то, что содержание первого оператора печати (Content-Type: text/html) не появляется на вашем браузере Веб. Вы можете отослать любую информацию, по Вашему усмотрению, назад на браузер (страницу HTML, графику или звук), но сначала, нужно сообщить браузеру какого вида данные вы ему посылаете. Эта строка сообщает браузеру какой вид информации ожидать - в данном случае, страницу HTML.

В-третьих, программа называется hello.cgi. Не всегда нужно использовать расширение.cgi с именем вашей программы CGI. Хотя исходный код для многих языков также использует расширение.cgi, оно не используется для обозначения типа языка, а является для сервера способом идентификации файла как исполняемого файла, а не графического файла, файла HTML или текстового файла. Серверы часто конфигурируются так, чтобы только попытаться выполнить те файлы, которые имеют это расширение, отображая содержание всех других. Хотя использование расширения.cgi не обязательно, это все еще считается хорошей практикой.

В общем, hello.cgi состоит из двух основных частей:

  • сообщает браузеру какую информацию ожидать (Content-Type: text/html)
  • сообщает браузеру, что отобразить (Hello, World!)

Hello, World! в C

Чтобы показать независимость программ CGI от языков, в листинг 2.2 показан эквивалент программы hello.cgi , написанной в C.

Листинг 2.2. Hello, World! в C. /* hello.cgi.c - Hello, World CGI */ #include int main() { printf("Content-Type: text/html\r\n\r\n"); printf(" \n"); printf("Hello, World!\n"); printf("\n"); printf("\n"); printf("

Hello, World!

\n"); printf(" \n"); }

Примечание

Обратите внимание на то, что версия Perl hello.cgi использует Content-Type print ": text/html\n\n "; В то время как версия C использует Printf (" Content-Type: text/html\r\n\r\n ");

Почему Perl печатает операторный конец с двумя символами новой строки (\n), в то время как C printf заканчивается двумя символами возврата каретки и новой строки(\r\n)?

Формально, заголовки (весь вывод перед пустой строкой) как предполагается, будут отделены символом возрата каретки и новой строки. К сожалению, на машинах DOS и Windows, Perl транслирует \r как другую новую строку, а не как перевод каретки.

Хотя исключение \rs в Perl технически неправильно, она будет работать почти во всех протоколах и так же переноситься всеми платформами. Поэтому, во всех примерах Perl в этой книге я использую новую строку, отделяющие заголовки, а не символы возврата каретки и новой строки.

Соответствующее решение этой проблемы представлено в Главе 4, "Вывод".

Ни серверу Веб, ни браузеру не важно, какой язык используется для записи программы. Хотя каждый язык имеет преимущества и недостатки в качестве языка программирования CGI, лучше использовать язык, с которым Вам удобнее всего работать. (Более детально выбор языка программирования обсуждается в Главе 1 "Общешлюзовой интерфейс (CGI) ").

Выведение CGI

Теперь можно внимательнее изучить вопрос отправки информации на браузер Веб. Из примера " Hello, World!", видно, что браузеры Веб ожидают два набора данных: заголовок, который содержит информацию, например какую информацию отобразить (например Content-Type: line) и фактическую информацию (что отображается на браузере Веб). Эти два блока информации отделены пустой строкой.

Заголовок называется заголовком HTTP. Он дает важные сведения об информации, которую браузер собирается получать. Имеются несколько различных типов заголовков HTTP, и наиболее универсальным является тот, который Вы использовали раньше: Content-Type: заголовок. Вы можете использовать различные комбинации заголовков HTTP, отделяя их символами возврата каретки и новой линии (\r\n). Пустая строка, отделяющая заголовок от данных, также состоит из возврата каретки и новой строки (почему нужны оба, кратко описано в предшествующем примечании и подробно в Главе 4). Вы узнаете о других заголовках HTTP в Главе 4; в данный момент Вы занимаетесь Content-Type: заголовок.

Content-Type: заголовок описывает тип данных, которые возвращает CGI. Соответствующим форматом для этого заголовка является:

Content-Type: subtype/type

Где subtype/type - правильный тип многоцелевых расширений почты Интернета (MIME). Наиболее распространенным типом MIME является тип HTML: text/html. В таблице 2.1 приведено еще несколько распространненых типов MIME, которые будут рассмотрены; более полный перечень и анализ типов MIME приводится в Главе 4.

Примечание

MIME было первоначально изобретено для описания содержания тел сообщений почты. Оно стало довольно распространненым способом представления информации о Content-Type . Вы можете узнать больше о MIME в RFC1521. RFCs в Интернете обозначают "Просьбы о комментариях", которые представляют собой резюме решений, принятых группами в Интернете, пытающимися установить стандарты. Можно посмотреть результаты RFC1521 на следующем адресе: http://andrew2.andrew.cmu.edu/rfc/rfc1521.html

Таблица 2.1. Некоторые общие типы MIME. Тип MIME Описание Text/html Язык разметки гипертекста (HTML) Text/plain Простые текстовые файлы Image/gif Графические файлы GIF Image/jpeg Сжатые графические файлы JPEG Audio/basic Аудио - файлы Sun *.au Audio/x-wav Файлы Windows *.wav

После заголовка и пустой строки, Вы просто печатаете данные в нужном для Вас виде. Если Вы посылаете HTML, то печатайте теги HTML и данные к stdout после заголовка. Вы можете послать также графику, звук и другие двоичные файлы, просто печатая содержимое файла в stdout. Несколько примеров этого приведено в Главе 4.

Установка и выполнение программы CGI

Данный раздел несколько отклоняется от программирования CGI и рассказывает о конфигурирования вашего сервера Веб для использования CGI, об установке и выполнении программ. Вы ознакомитесь с различными серверами для различных платформ более или менее подробно, но Вам придется глубже изучить документацию своего сервера с целью нахождения оптимального варианта.

Все серверы требуют пространства для файлов сервера и пространства для документов HTML. В настоящей книге, область сервера называется ServerRoot, а область документа - DocumentRoot. На машинах UNIX ServerRoot - обычно в /usr/local/etc/httpd/, а DocumentRoot - обычно в /usr/local/etc/httpd/htdocs/. Однако, это не имеет никакого значения для вашей системы, поэтому замените все ссылки на ServerRoot и DocumentRoot на ваши собственные ServerRoot и DocumentRoot.

Когда Вы обращаетесь к файлам, используя ваш браузер Веб, Вы определяете файл в URL относительно DocumentRoot. Например, если адрес вашего сервера mymachine.org, то Вы обращаетесь к этому файлу со следующим URL: http://mymachine.org/index.html

Конфигурирование сервера для CGI

Большинство серверов Веб имеет такую предварительную конфигурацию, которая позволяет использовать программы CGI. Обычно два параметра указывают серверу о том, является ли файл приложением CGI или нет:

  • Обозначенный каталог. Некоторые серверы позволяют определить, что все файлы в обозначенном каталоге (обычно, по умолчанию, называемый cgi-bin) являются CGI.
  • Расширения имени файла. Много серверов имеют такую предварительную конфигурацию, которая позволяет определять все файлы заканчивающиеся на.cgi, как CGI.

Метод обозначенного каталога - это своего рода пережиток прошлого (самые первые серверы использовали его как единственный метод для определения того, какие файлы были программами CGI), но он имеет несколько преимуществ.

  • Он сохраняет программы CGI в централизованном виде, препятствуя загромождению других каталогов.
  • Вы не ограничены каким-либо определенным расширением имени файла, так что можете называть файлы так, как хотите. Некоторые серверы позволяют обозначить несколько различных каталогов в качестве каталогов CGI.
  • Он также дает больше возможностей в отношении контроля над теми, кто может записывать CGI. Например, если Вы имеете сервер и поддерживаете систему с несколькими пользователями и не хотите, чтобы они использовали свои собственные сценарии CGI без предварительной ревизии программы из соображений безопасности, можно обозначить только эти файлы в ограниченном,централизованном каталоге как CGI. Пользователи тогда должны будут предоставить Вам программы CGI для установки и Вы сможете сначала провести ревизию кода, чтобы удостовериться, что у программы нет каких-либо крупных проблем с защитой.

Обозначение CGI через расширение имени файла может быть полезно благодаря его гибкости. Вы не ограничены одним единственным каталогом для программ CGI. Большинство серверов может быть конфигурировано, чтобы распознать CGI через расширение имени файла, хотя по умолчанию не все из них конфигурированы таким образом.

Предостережение

Помните о важности вопросов защиты, когда Вы конфигурируете ваш сервер для CGI. Некоторые подсказки будут рассмотрены здесь, а в Главе 9 "Защита CGI" эти аспекты рассматриваются более подробно.

Установка CGI на серверах UNIX

Независимо от того, как конфигурирован ваш сервер UNIX, нужно предпринять несколько шагов, чтобы удостовериться в том, что ваши приложения CGI выполняются должным образом. Ваш сервер Веб обычно будет работать как несуществующий пользователь (то есть пользователь UNIX nobody - учетная запись, которая не имеет прав доступа к файлу и не может быть зарегистрирована). Сценарии CGI (написанные на Perl, оболочке Bourne или на другом языке описания сценария) должны быть, выполнимы и читаемы по всему миру.

Подсказка

Чтобы сделать ваши файлы читаемыми и выполнимым по всему миру, используйте следующую команду UNIX права доступа: chmod 755 имени файла.

Если Вы используете язык описания сценария типа Perl или Tcl, укажите полный путь вашего интерпретатора в первой строке вашего сценария. Например, сценарий Perl, использующий perl в каталоге /usr/local/bin должен начинаться со следующей строки:

#!/usr/local/bin/perl

Предостережение

Никогда не помещайте интерпретатор (perl, или двоичный код Tcl Wish в каталог /cgi-bin. Это создает опасность для защиты в Вашей системе. Более подробно это описано в Главе 9.

Некоторые универсальные cерверы UNIX

Серверы NCSA и Apache имеют файлы со сходной конфигурацией, потому что сервер Apache был первоначально основан на коде NCSA. По умолчанию, они конфигурированы таким образом, чтобы любой файл в каталоге cgi-bin (расположенный по умолчанию в ServerRoot) являлся программой CGI. Чтобы изменить местоположение каталога cgi-bin, можно отредактировать файл конфигурации conf/srm.conf. Форматом для конфигурирования этого каталога является

ScriptAlias fakedirectoryname realdirectoryname

где fakedirectoryname - псевдо-имя каталога (/cgi-bin), и realdirectoryname - полный путь, где программы CGI фактически сохранены. Вы можете конфигурировать более одного ScriptAlias, добавляя еще строки ScriptAlias.

Заданная по умолчанию конфигурация достаточна для потребностей большинства пользователей. Нужно отредактировать строку в файле srm.conf в любом случае, чтобы определить правильное realdirectoryname. Если, например, Ваши программы CGI расположены в /usr/local/etc/httpd/cgi-bin, строка ScriptAlias в вашем файле srm.conf должна походить на следующую:

ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-bin/

Чтобы обращаться или ссылаться на программы CGI, расположенные в этом каталоге, используется следующий URL:

Http://hostname/cgi-bin/programname

Где hostname - имя хозяина вашего сервера Веб, и programname - имя Вашего CGI.

Например, допустим, что Вы скопировали программу hello.cgi в Ваш каталог cgi-bin (например, /usr/local/etc/httpd/cgi-bin) на Вашем сервере Веб, называемом www.company.com. Чтобы обратиться к вашему CGI, используйте следующий URL: http://www.company.com/cgi-bin/hello.cgi

Если нужно конфигурировать сервер NCSA или Apache так, чтобы распознавать любой файл с расширением.cgi как CGI, нужно отредактировать два файла конфигурации. Сначала, в файле srm.conf, не комментируйте следующую строку:

AddType application/x-httpd-cgi .cgi

Это свяжет CGI типа MIME с расширением.cgi. Теперь, нужно изменить файл access.conf, чтобы можно было выполнить CGI в любом каталоге. Для этого, добавьте опцию ExecCGI к строке Option. Это будет выглядеть примерно как следующая строка:

Option Indexes FollowSymLinks ExecCGI

Теперь, любой файл с расширением.cgi считается CGI; обращайтесь к нему, как обращались бы к любому файлу на вашем сервере.

Сервер CERN конфигурирован так же, как и серверы Apache и NCSA. Вместо ScriptAlias, сервер CERN использует команду Exec. Например, в файле httpd.conf, Вы увидете следующую строку:

Exec /cgi-bin/* /usr/local/etc/httpd/cgi-bin/*

Другие серверы UNIX можно конфигурировать таким же способом; более подробно об этом описано в документации сервера.

Установка CGI на Windows

Большинство серверов, доступных для Windows 3.1, Windows 95 и Windows NT конфигурировано с помощью метода "расширение имени файла" для распознавания CGI. Вообще, изменение конфигурации сервера на базе Windows просто требует выполнения программы конфигурации сервера и внесения соответствующих изменений.

Иногда конфигурирование сервера для правильного выполнения сценарий (типа Perl) представляется сложным делом. В DOS или Windows, Вы не сможете определить интерпретатор на первой строке сценария, как это происходит при работе с UNIX. Некоторые серверы имеют заранее заданную конфигурацию, чтобы связать некоторые расширения имени файла с интерпретатором. Например, многие Веб-серверы Windows предполагают, что файлы, оканчивающиеся на.pl, являются сценариями Perl.

Если сервер не выполняет такой тип ассоциации файла, можно определить пакетный файл упаковщика, который вызывает как иинтерпретатор, так и сценарий. Как и с сервером UNIX, не устанавливайте интерпретатор ни в каталоге cgi-bin ни в каком-либо Веб-доступном каталоге.

Установка CGI на Macintosh

Две наиболее известные опции сервера для Macintosh - это WebStar StarNine и его предшественник MacHTTP. Оба распознают CGI по расширению имени файла.

MacHTTP понимает два различных расширения: .cgi и.acgi, который обозначает асинхронный CGI. Регулярные программы CGI, установленные на Macintosh (с расширением.cgi), будут поддерживать Веб-сервер в состоянии занятости, пока не закончится выполнение CGI, вынуждая сервер приостановить выполнение всех других запросов. Асинхронный CGI, с другой стороны, позволяет серверу принимать запросы даже во время своей работы.

Разработчик CGI Macintosh, использующий любой из этих Веб-серверов, должен, по возможности, использовать просто расширение.acgi, а не расширение.cgi. Оно должно работать с большинством программ CGI; если оно не работает, переименуйте программу на.cgi.

Выполнение CGI

После того, как вы установили CGI, имеются несколько способов выполнить его. Если ваш CGI -программа, работающая только с выводом, типа программы Hello,World!, тогда Вы может выполнять ее, просто обращаясь к ее URL.

Большинство программ выполняется как серверное приложение к форме HTML. Прежде, чем научиться, как получать информацию от этих форм, сначала прочтите краткое введение о создании таких форм.

Быстрая обучающая программа по формам HTML

Два наиболее важных тега в форме HTML - это теги и . Можно создавать большинство форм HTML, используя только эти два тега. В данной главе, Вы изучите эти теги и небольшое подмножество возможных типов или атрибутов . Полное руководство и ссылка на формы HTML находятся в Главе 3 " HTML и формы" .

Тег

Тег используется для определения того, какая часть файла HTML должна быть использована для информации, введенной пользователем. Здесь имеется в виду, как большинство страниц HTML вызывает программу CGI. Атрибуты тега определяют имя программы и местоположение - либо локально, либо как полный URL, тип используемого кодирования, и метод перемещения данных, используемых программой.

Следующая строка показывает спецификации для тега :

< ACTION FORM = "url" METHOD = ENCTYPE = "..." >

Атрибут ENCTYPE не играет особой роли и обычно не включается с тегом . Подробная информация относительно тега ENCTYPE дана в Главе 3. Один из способов использования ENCTYPE, показан в Главе 14 "Фирменные расширения. "

Атрибут ACTION ссылается на URL программы CGI. После того, как пользователь заполнит форму и предоставит информацию, вся информация кодируется и передается программе CGI. Программа CGI решает сама вопрос о декодировании и обработке информации; этот аспект рассматривается в "Принятие ввода от браузера, " ниже в настоящей главе.

Наконец, атрибут METHOD описывает, как программа CGI должна получать ввод. Эти два методы - GET и POST - отличаются в отношении того, как передавать информацию программе CGI. Оба обсуждены в "Принятие ввода от браузера. "

Чтобы браузер смог позволить введение информации пользователем, все теги форм и информация должны быть окружены тегом . Не забудьте заключительный тег

для обозначения конца формы. Нельзя иметь форму внутри формы, хотя Вы можете установить форму, которая позволяет представлять части информации в различные местах; этот аспект широко рассматривается в Главе 3.

Тег

Вы можете создавать полоски ввода текста, кнопки "radio", окна флажков, и другие средства принятия ввода, используя тег. В данном разделе рассматриваются только поля текстового ввода. Для реализации этого поля, используйте тег со следующими атрибутами:

< INPUT TYPE=text NAME = "... " VALUE = "... " SIZE = MAXLENGTH = >

NAME - символическое имя переменной, которая содержит значение, введенное пользователем. Если Вы включаете текст в атрибут VALUE, этот текст будет помещен как заданный по умолчанию в поле текстового ввода. Атрибут SIZE позволяет Вам определить горизонтальную длину поля ввода, поскольку он будет появляться в окне браузера. И наконец, MAXLENGTH определяет максимальное число символов которые, пользователь может ввести в поле. Обратите внимание, что атрибуты VALUE, SIZE, MAXLENGTH являются необязательными.

Представление формы

Если Вы имеете только одно текстовое поле в пределах формы, пользователь может представить форму, просто набирая информацию на клавиатуре и нажимая Enter. В противном случае, должен быть какой-то другой способ представления информации пользователем. Пользователь представляет информацию, используя кнопку для представления со следующим тегом:

< Input type=submit >

Этот тег создает внутри вашей формы кнопку Submit. Когда пользователь закончивает заполнение формы, он или она может отправить ее содержание по адресу URL, указанному атрибутом ACTION формы, кликая кнопку Submit.

Принятие ввода от браузера

Выше были даны примеры записи программы CGI, которая посылает информацию с сервера на браузер. В действительности, программа CGI, которая лишь выводит данные, не имеет много приложений (некоторые примеры даны в Главе 4). Более важной способностью CGI является получение информации от браузера - особенность, которая придает Веб интерактивный характер.

Программа CGI получает два вида информации от браузера.

  • Во-первых, она получает различные части информации о браузере (его тип, что он может просматривать, хост хозяина, и так далее), сервера (его имя и версия, порт его выполнения, и так далее), и непосредственно о программе CGI (имя программы и где она расположена). Сервер дает всю эту информацию программе CGI через переменные среды.
  • Во-вторых, программа CGI может получать информацию, введенную пользователем. Эта информация, после кодирования браузером, посылается либо через переменную среду (метод GET), либо через стандартный ввод (stdin- метод POST).

Переменные среды

Полезно знать, какие переменные среды являются доступными для программы CGI, как в процессе обучения, так и для отладки. В таблице 2.2 приведены некоторые из доступных переменных среды CGI. Можно также записать программу CGI, которая выводит переменные среды и их значения на браузер Веб.

Таблица 2.2. Некоторые важные переменные среды CGI Переменная среды Цель REMOTE_ADDR Адрес IP машины клиента. REMOTE_HOST Хост хозяина машины клиента. HTTP _ACCEPT Перечисляет типы MIME данных, которые браузер умеет интерпретировать. HTTP _USER_AGENT Информация браузера (тип браузера, номер версии, операционная система, и т.д.). REQUEST_METHOD GET или POST. CONTENT_LENGTH Размер ввода, если он послан через POST. Если не имеется никакого ввода или если используется метод GET, этот параметр не определен. QUERY_STRING Содержит вводимую информацию, когда она передается с помощью метода GET. PATH_INFO Позволяет пользователю определить путь от командной строки CGI (например, http://hostname/cgi-bin/programname/path). PATH_TRANSLATED Транслирует относительный путь в PATH_INFO в фактический путь в системе.

Чтобы записать приложение CGI, которое отображает переменные среды, нужно знать, как выполнить две вещи:

  • Определить все переменные среды и их соответствующие значения.
  • Вывести результаты для браузера.

Вы уже знаете, как выполнять последнюю операцию. В Perl переменные среды сохраняются в ассоциативном массиве %ENV, который вводится именем переменной среды. Листинг 2.3 содержит env.cgi, программу Perl, которая служит для достижения нашей цели.

Листинг 2.3. Программа Perl, env.cgi, которая выводит все переменные среды CGI.

#!/usr/local/bin/perl print "Content-type: text/html\n\n"; print " \n"; print "CGI Environment\n"; print "\n"; print "\n"; print "

CGI Environment

\n"; foreach $env_var (keys %ENV) { print "$env_var = $ENV{$env_var}
\n"; } print " \n";

Подобная программа может быть написана в C; полный код находится в Листинге 2.4.

Листинг 2.4. Env.cgi.c в C. /* env.cgi.c */ #include extern char **environ; int main() { char **p = environ; printf("Content-Type: text/html\r\n\r\n"); printf(" \n"); printf("CGI Environment\n"); printf("\n"); printf("\n"); printf("

CGI Environment

\n"); while(*p != NULL) printf("%s
\n",*p++); printf(" \n"); }

GET или POST ?

Какая разница между методами GET и POST? GET передает закодированную входную строку через переменную среды QUERY_STRING, а POST передает ее через stdin. POST - более предпочтительный метод, особенно для форм с большим количеством данных, потому-что здесь нет каких-либо ограничений в отношении объема посылаемой информации, а при методе GET объем пространства среды ограничен. GET имеет однако определенное полезное свойство; это подробно рассматривается в Главе 5 "Ввод".

Чтобы определить, который метод используется, программа CGI проверяет переменную среду REQUEST_METHOD, которая будет установлена либо в GET, либо в POST. Если она установлена в POST, длина закодированной информации сохранена в переменной среды CONTENT_LENGTH.

Закодированный Ввод

Когда пользователь передает форму, браузер сначала кодирует информацию перед посылкой ее на сервер, а затем на приложение CGI. Когда Вы используете тег , каждому полю присваивают символическое имя. Значение, введенное пользователем, представляется как значение переменной.

Чтобы определить это, браузер использует кодирующую спецификацию URL, которая может быть описана следующим образом:

  • Отделяет различные поля амперсандом (&).
  • Отделяет имя и значения знаками равенства (=), с именем слева и значением справа.
  • Заменяет пробелы знаками "плюс" (+).
  • Заменяет все "ненормальные" символы знаком процента (%), за которым следует двузначный шестнадцатеричный код символа.

Ваша конечная закодированная строка будет похожа на следующую:

Name1=value1&name2=value2&name3=value3 ...

Примечание: Спецификации для кодирования URL находятся в RFC1738.

Например, предположим, что у вас была форма, которая запросила имя и возраст. Код HTML, который использовался для отображения этой формы, представлен в листинге 2.5.

Листинг 2.5. Код HTML для отображения формы имени и возраста.

Name and Age

Enter your name:

Enter your age:

Предположим, что пользователь вводит Joe Schmoe в поле имени, и 20 - в поле возраста. Ввод будет закодирован во входной строке.

Name=Joe+Schmoe&age=20

Синтаксический анализ ввода

Для того чтобы эта информация была полезной, нужно использовать информацию на что-то такое, что может быть использовано вашими программами CGI. Стратегии синтаксического анализа ввода рассматриваются в Главе 5. Практически, Вам никогда не придется думать о том, как анализировать ввод, потому что несколько специалистов уже написали доступные для всех библиотеки, которые производят синтаксический анализ. Две такие библиотеки представлены в настоящей главе в следующих разделах: cgi -lib.pl для Perl (написаны Стивом Бреннером) и cgihtml для C (написаны мной).

Общая цель большинства библиотек, написанных на различных языках, состоит в том, чтобы анализировать закодированную строку и помещать пары имен и значений в структуру данных. Имеется очевидное преимущество в использовании языка, который имеет встроенные структуры данных типа Perl; однако, большинство библиотек для языков низшего уровня типа C и C++ включает выполнение структуры данных и подпрограммы.

Не обязательно добиваться полного понимания библиотек; гораздо важнее научиться использовать их как инструментальные средства, чтобы упростить работу программиста CGI.

Cgi -lib.pl

Cgi -lib.pl использует ассоциативные массивы Perl. Функция &ReadParse анализирует входную строку и вводит каждую пару "имя / значение" по имени. Например, соответствующими строками Perl, необходимыми для декодирования только что представленной вводной строки "имя / возраст", были бы

&ReadParse(*input);

Теперь, чтобы увидеть значение, введенное для "имени", можно обращаться к ассоциативному массиву $input {"имя"}. Точно так же, чтобы обратиться к значению "возраста", нужно посмотреть на переменную $input {"возраст"}.

Cgihtml

C не имеет никаких встроенных структур данных, так что cgihtml осуществляет свой собственный список связей для использования со своими анализирующими подпрограммами CGI. Это определяет структуру entrytype следующим образом:

Typedef struct { Char *name; Char *value; } Entrytype;

Чтобы проанализировать вводную строку "name / age" ("имя / возраст") в C, используя cgihtml, используется следующее:

/* объявить связанный список, называемый вводом */ Llist input; /* анализировть ввод и место в связанном списке */ read_cgi_input(&input);

Чтобы обратиться к информации о возрасте, можно либо проанализировать список вручную, либо использовать имеющуюся функцию cgi _val ().

#include #include Char *age = malloc (sizeof (char) * strlen (cgi _val (input, "age")) + 1); Strcpy (age, cgi _val (input, "age"));

Значение "возраста" теперь сохранено в строке age.

Примечание: Вместо использования простого массива (подобно char age ;), я занимаюсь динамическим распределением пространства памяти для строки age. Хотя это усложняет программирование, тем не менее это важно с точки зрения безопасности. Более подробно о этом говорится в Главе 9.

Простая программа CGI

Вы собираетесь записать программу CGI, называемую nameage.cgi, которая обрабатывает форму "имя / возраст". Обработка данных (что я обычно называю "промежуточным материалом") минимальна. Nameage.cgi просто декодирует ввод и отображает имя пользователя и возраст. Хотя не особенно много пользы от такого инструмента, он демонстрирует наиболее критический аспект программирования CGI: ввод и вывод.

Вы используете ту же самую форму, как описано выше, вызывая поля "имя и возраст". Пока не стоит беспокоиться об ошибкоустойчивости и эффективности; решите имеющуюся задачу простейшим образом. Решения в Perl и C показаны соответственно в листингах 2.6 и 2.7.

Листинг 2.6. Nameage.cgi в Perl

#!/usr/local/bin/perl # nameage.cgi require "cgi-lib.pl" &ReadParse(*input); print "Content-Type: text/html\r\n\r\n"; print " \n"; print "Name and Age\n"; print "\n"; print "\n"; print "Hello, " . $input{"name"} . ". You are\n"; print $input{"age"} . " years old.

\n"; print " \n";

Листинг 2.7. nameage.cgi в C

/* nameage.cgi.c */ #include #include "cgi-lib.h" int main() { llist input; read_cgi_input(&input); printf("Content-Type: text/html\r\n\r\n"); printf(" \n"); printf("Name and Age\n"); printf("\n"); printf("\n"); printf("Hello, %s. You are\n",cgi_val(input,"name")); printf("%s years old.

\n",cgi_val(input,"age")); printf(" \n"); }

Обратите внимание на то, что эти две программы почти эквивалентны. Они обе содержат подпрограммы синтаксического анализа, которые занимают только одну строку и обрабатывают весь ввод (благодаря соответствующим библиотечным подпрограммам). Вывод, по существу, является измененной версией вашей основной программы Hello, World!.

Попытайтесь выполнить программу, заполняя форму и нажимая кнопку Submit.

Общая стратегия программирования

Вы теперь знаете все основные принципы, необходимые для программирования CGI. Когда Вы понимаете, как CGI получает информацию и как он отсылает ее назад браузеру, фактическое качество вашего конечного продукта зависит от ваших общих способностей к программированию. А именно, когда Вы программируете CGI (или вообще что - нибудь, если уж на то пошло), помните о следующих качествах:

  • Простота
  • Эффективность
  • Универсальность

Первые два качества достаточно распространены: старайтесь сделать код как можно более читаемым и эффективным. Универсальность больше относится к программам CGI, чем к другим приложениям. Когда Вы начнете разрабатывать свои собственные программы CGI, Вы узнаете, что имеется несколько основных приложений, которые хочет сделать каждый. Например, одна из наиболее распространенных и очевидных задач программы CGI является обработка формы и посылка по электронной почте результатов определенному получателю. Вы могли бы иметь несколько отдельных обработанных форм, каждая с различным получателем. Вместо записи программы CGI для каждой отдельной формы, Вы можете съэкономить время, написав более общую программу CGI, которая годится для всех форм.

Затронув все основные аспекты CGI, я обеспечил Вас достаточными сведениями, чтобы начать программирование CGI. Однако чтобы стать эффективным разработчиком CGI, нужно иметь более глубокое понимание того, как CGI связывается с сервером и браузером. В оставшейся части настоящей книги подробно рассматриваются те вопросы, о которых вскользь было упомянуто в данной главе, а также вопросы стратегии разработки приложений, преимущества и ограничения протокола.

Резюме

В настоящей главе вкратце были описаны основы программирования CGI. Вы создаете вывод, правильно форматируя ваши данные и печатая в stdout. Получение ввода CGI является несколько более сложным делом, потому что он должен быть проанализирован до своего использования. К счастью, уже существуют несколько библиотек, которые осуществляют синтаксический анализ.

К данному моменту Вы должны достаточно легко справиться с программированием приложений CGI. Оставшаяся часть настоящей книги посвящена более подробному изложению спецификации, подсказкам и стратегии программирования более продвинутых и сложных приложений.

Технология CGI - Common Gateway Interface

CGI - Common Gateway Interface является стандартом интерфейса (связи) внешней прикладной программы с информационным сервером типа HTTP, Web сервер. Обычно гипертекстовые документы, извлекаемые из WWW серверов, содержат статические данные. С помощью CGI можно создавать CGI-программы, называемые шлюзами , которые во взаимодействии с такими прикладными системами, как система управления базой данных, электронная таблица, деловая графика и др., смогут выдать на экран пользователя динамическую информацию.

Программа-шлюз запускается WWW сервером в реальном масштабе времени. WWW сервер обеспечивает передачу запроса пользователя шлюзу, а она в свою очередь, используя средства прикладной системы, возвращает результат обработки запроса на экран пользователя. Программа-шлюз может быть закодирована на языках C/C++, Fortran, Perl, TCL, Unix Schell, Visual Basic, Apple Script. Как выполнимый модуль, она записывается в поддиректорий с именем cgi-bin WWW сервера.

Передача данных шлюзам

Для передачи данных об информационном запросе от сервера к шлюзу, сервер использует командную строку и переменные окружения. Эти переменные окружения устанавливаются в тот момент, когда сервер выполняет программу шлюза.

Запросы для различных методов

Информация шлюзам передается в следующей форме:

имя=значение&имя1=значение1&..,

где имя- имя переменной (из оператора FORM , например), и значение - ее реальное значение. В зависимости от метода, который используется для запроса, эта строка появляется или как часть URL (в случае метода GET ), или как содержимое HTTP запроса (метод POST ). В последнем случае, эта информация будет послана шлюзу в стандартный поток ввода.

На файловый дескриптор стандартного потока ввода посылается CONTENT_LENGTH байт. Так же сервер передает шлюзу CONTENT_TYPE (тип передаваемых данных). Сервер не обязан посылать символ конца файла после отсылки CONTENT_LENGTH байт данных и после того, как шлюз их прочитает.

Пример

Возьмем результат работы формы с методом POST (METHOD="POST") в качестве примера. Пусть получено 7 байт, закодированных примерно так:
a=b&b=c.

В этом случае, сервер установит значение CONTENT_LENGTH равным 7 и CONTENT_TYPE в application/x-www-form-urlencoded. Первым символом в стандартном потоке ввода для шлюза будет "a", за которым будет следовать остаток закодированной строки.

Аргументы командной строки

Шлюз в командной строке от сервера получает:

  • остаток URL после имени шлюза в качестве первого параметра (первый параметр будет пуст, если присутствовало только имя шлюза), и
  • список ключевых слов в качестве остатка командной строки для скрипта поиска, или
  • чередующиеся имена полей формы с добавленным знаком равенства (на четных позициях) и соответствующих значений переменных (на нечетных позициях).

Ключевые слова, имена полей формы и значения передаются раскодированными (из HTTP URL формата кодирования) и перекодированными в соответствии с правилами кодирования Bourne shell, так что шлюз в командной строке получит информацию в том виде, как она есть, без необходимости осуществлять дополнительные преобразования.

Запросы оператора FORM

Запросы оператора FORM обрабатываются таким образом, что каждый параметр, отвечающий за имя поля, оканчивается знаком равенства, а остаток представляет собой значение этого параметра. Если присутствует что либо после имени скрипта (шлюза), то эта информация передается в качестве первого параметра. Иначе первый параметр будет пуст.

Примеры:

/htbin/foo/x/y/z?name1=value1&name2=value2 вызывается как: /.../foo /x/y/z name1= value1 name2= value2 а /htbin/foo?name1=value1&name2=value2 вызывается как: /.../foo "" name1= value1 name2= value2

CGI переменные окружения

Следующие переменные окружения не являются специфичными по типу запросов и устанавливаются для всех запросов.

SERVER_SOFTWARE Название и версия информационного сервера, который отвечает на запрос (и запускает шлюз). Формат: имя/версия SERVER_NAME Имя хоста, на котором запущен сервер, DNS имя, или IP адрес в том виде, в котором он представлен в URL. GATEWAY_INTERFACE Версия CGI спецификации на тот момент, когда компилировался сервер. Формат: CGI/версия

Следующие переменные окружения являются специфичными для разных запросов, и заполняются перед вызовом шлюза: SERVER_PROTOCOL Имя и версия информационного протокола, в котором пришел запрос. Формат: протокол/версия SERVER_PORT Номер порта, на который был послан запрос REQUEST_METHOD Метод, который был использован для запроса. Для HTTP, это GET , HEAD , POST , и т.д. PATH_INFO Дополнительная информация о пути, которую передал клиент. Другими словами, доступ к шлюзу может быть осуществлен по виртуальному пути, за которым следует некоторая дополнительная информация. Эта информация передается в PATH_INFO. PATH_TRANSLATED Сервер передает преобразованную версию PATH_INFO, которая включает в себя путь, преобразованный из виртуального в физический. SCRIPT_NAME Виртуальный путь к шлюзу, который должен выполняться, используемый для получения URL. QUERY_STRING Информация, следующая за? в URL, к которому относится данный шлюз. Это информация представляет собой строку запроса. Она не должна быть декодирована никоим образом. Вне зависимости от командной строки эта переменная всегда должна быть установлена при наличии такой информации, . REMOTE_HOST Имя хоста, производящего запрос. Если сервер не имеет такой информации, он должен установить REMOTE_ADDR, а это поле оставить не установленным. REMOTE_ADDR IP адрес хоста, производящего запрос. AUTH_TYPE Если сервер поддерживает идентификацию пользователя, и шлюз является защищенным от постороннего доступа, этот специфичный для протокола метод идентификации используется для проверки пользователя. REMOTE_USER Используется в ситуациях, аналогичных предыдущему случаю, для хранения имени пользователя. REMOTE_IDENT Если HTTP сервер поддерживает идентификацию пользователя согласно RFC 931, то эта переменная будет содержать имя пользователя, полученное от сервера. CONTENT_TYPE Для запросов, которые содержат дополнительную добавочную информацию, такие как HTTP POST и PUT, здесь содержится тип данных этой информации. CONTENT_LENGTH Длина данных, которую передает клиент.

В дополнение к этим, если запрос содержит дополнительные поля заголовка запроса, они помещаются в переменные окружения с префиксом HTTP_, за которым следует имя заголовка. Любые символы "-" в заголовке меняются на символы подчеркивания "_". Сервер может исключить любые заголовки, которые он уже обработал, такие как Authorization, Content-type, и Content- length. Если необходимо, сервер может исключить любые (или вообще все) дополнительные поля заголовка в случае, когда их включение может привести к превышению предела размера переменных окружения. Примером такой переменной может служить переменная HTTP_ACCEPT, которая была определена в спецификации CGI/1.0. Другим примером может служить заголовок User-Agent.

HTTP_ACCEPT Список MIME типов, которые клиент может обработать, как задано в HTTP заголовках. Другие протоколы должны получить эту информацию из других мест (если она им необходима). Каждый тип в этом списке должен быть отделен запятой согласно HTTP спецификации. Формат: тип/подтип, тип/подтип HTTP_USER_AGENT Просмотрщик, который использует клиент для посылки запроса. Общий формат: программа/версия библиотека/версия.

Вывод информации шлюзом

Основные концепции

Шлюз осуществляет свой вывод в стандартный поток вывода. Этот вывод может представлять собой или документ, сгенерированный шлюзом, или инструкции серверу, где получить необходимый документ.

Как правило, шлюз производит свой вывод, который интерпретируется и посылается обратно клиенту. Преимущество этого подхода состоит в том, что шлюз не должен посылать полный HTTP/1.0 заголовок на каждый запрос.

Заголовок выходного потока

Для некоторых шлюзов может быть необходимо избегать обработки сервером их вывода, и общаться с клиентом непосредственно. Для того, чтобы отличить такие шлюзы от остальных, CGI требует, чтобы их имена начинались с префикса nph-. В этом случае, на шлюзе лежит ответственность за возвращение клиенту синтаксически правильного ответа.

Заголовки с синтаксическим разбором

Вывод шлюза начинается с маленького заголовка. Он содержит текстовые строки, в том же формате, как и в HTTP заголовке и завершается пустой строкой (содержащей только символ перевода строки или CR/LF).

Любые строки заголовка, не являющиеся директивами сервера, посылаются непосредственно клиенту. В настоящий момент, CGI спецификация определяет три директивы сервера: Content-type MIME тип возвращаемого документа. Location Это поле используется в случае, когда необходимо указать серверу, что возвращается не сам документ, а ссылка на него.

Если аргументом является URL, то сервер передаст клиенту указание на перенаправление запроса. Если аргумент представляет собой виртуальный путь, сервер вернет клиенту заданный этим путем документ, как если бы клиент запрашивал его непосредственно.

  • Status

Эта директива используется для задания серверу HTTP/1.0 строки-статус, которая будет послана клиенту. Формат: nnn xxxxx, где nnn - 3-х цифровой статус-код, и xxxxx строка причины, такая, как "Forbidden" (Запрещено).

Примеры

Предположим, имеется некоторый текстовый конвертер в HTML. Когда он оканчивает свою работу, он должен произвести следующий вывод в стандартный выходной поток:

Начало вывода - Content-type: text/html - конец вывода - Теперь рассмотрим шлюз, который, в некоторых случаях, должен выдать документ /path/doc.txt с данного сервера, как если бы он был непосредственно востребован клиентом через http://server:port/path/doc.txt. В это случае вывод шлюза будет таков: - начало вывода - Location: /path/doc.txt - конец вывода - Наконец, предположим, что шлюз возвращает ссылки на gopher сервер, например на gopher://gopher.ncsa.uiuc.edu/. Вывод шлюза будет следующий: - начало вывода - Location: gopher://gopher.ncsa.uiuc.edu/ - конец вывода - Non-parsed headers

Допустим теперь, что у нас имеется шлюз, который общается с клиентом непосредственно. Как уже отмечалось, его имя должно начинаться с префикса nph- и он должен возвращать допустимый HTTP заголовок. В этом случае, если доступ к шлюзу был осуществлен со значением SERVER_PROTOCOL равным HTTP/1.0, его вывод должен удовлетворять HTTP/1.0:

Начало вывода - HTTP/1.0 200 OK Server: NCSA/1.0a6 Content-type: text/plain - конец вывода -


Часть 6. World Wide Web

WWW (World Wide Web — Всемирная паутина) — самый популярный сервис Интернета. Именно он, благодаря своей относительной простоте и наглядности для пользователей, сделал столь массовыми обращения к ресурсам Сети. Итак, что же такое WWW и как работает данная служба?

Самом общем плане WWW — это система Web-серверов, поддерживающая документы, форматированные специальным образом. Служба WWW реализована в виде клиент-серверной архитектуры. Пользователь с помощью клиентской программы (браузера) осуществляет запрос той или иной информации на сервере, а Web-сервер обслуживает запрос браузера. Браузер — это программа, обеспечивающая обращение к искомому ресурсу на сервере по его URL (универсальному адресу ресурса), интерпретирующая полученный результат и демонстрирующая его на клиентском компьютере (рис. 1).

Сервер и клиент обычно работают на разных компьютерах, а возможно, и на разных аппаратных платформах, и под управлением разных операционных систем.

Протокол, по которому происходит доставка Web-сервером документа Web-браузеру, носит название HTTP (Hypertext Transfer Protocol — Протокол передачи гипертекста). Для того чтобы подробнее объяснить механизм просмотра документов на Web-сервере, необходимо ввести несколько понятий, и прежде всего понятие гипертекста.

Гипертекст

ипертекст (Hypertext) — это текст, содержащий гиперссылки, связывающие слова или картинки документа с другим ресурсом (с каким-нибудь еще документом или с иным разделом этого же документа), при этом подобные «связанные» слова или картинки документа, как правило, выделяются, обычно с помощью подчеркивания. Пользователь может активировать эту связь щелчком мыши. В большинстве случаев подобная активизация ссылки приводит к тому, что вызываемый таким образом ресурс замещает текущий документ. Связать гиперссылкой можно не только слово, но и целый раздел документа и даже область конкретной формы на какой-либо картинке документа.

Некоторые авторы определяют гипертекстовый документ как документ, содержащий меню для перехода к другим ресурсам. Идею гипертекстовой организации документа можно проиллюстрировать на примере справочников. Если художественную книгу мы обычно читаем с начала и до конца (линейно), то справочную литературу мы чаще всего читаем нелинейно: например, встретив незнакомое слово, ищем его в приложении или в толковом словаре, затем вновь возвращаемся к начатому тексту и так далее. Иными словами, мы обращаемся к разным разделам справочника по мере необходимости.

В принципе, идея нелинейного прочтения текста возникла задолго до появления компьютеров. Известно, например, что в толковании на книгу псалмов Гильберта Порретанского (около 1150 года н.э.) применялись специальные пометки на полях, которые отсылали читателя на страницы в других местах книги.

Практическое применение идеи и сам термин «гипертекст» появились с возникновением электронных документов, хотя и существенно раньше, чем сама служба WWW. Впервые термин «гипертекст» был употреблен Тедом Нельсоном (Ted Nelson) в 1965 году. Существенный вклад в развитие гипертекстовых систем внесла фирма Apple.

Поскольку современные электронные документы содержат не только текст, но и любую мультимедийную информацию (текст, графика, звук), в качестве ссылок стали использовать не только текстовые, но и графические объекты. Со временем понятие гипертекста было расширено до понятия гипермедиа. Гипермедиа — это метод организации мультимедийной информации на основе ссылок на разные типы данных. Гипермедиадокументы используются не только в WWW. Типичным примером гипермедиа является мультимедийная информация, содержащаяся в электронной энциклопедии. Читая, к примеру, текст о певчих птицах в CD-ROM-энциклопедии, вы можете перейти на соответствующую ссылку и послушать пение выбранной птицы, а затем посмотреть видеоролик с записью ее полета.

Особенно продуктивной идея гипертекста оказалась применительно к объединению цифровой информации, распределенной на серверах во всем мире. Вот здесь мы непосредственно подходим к понятию Всемирной паутины.

Всемирная паутина

WW — это глобальная гипертекстовая система, организованная на базе Интернета. WWW представляет собой механизм, при помощи которого связывается информация, доступная посредством многочисленных Web-серверов во всем мире. Web-сервер — это программа, которая «умеет» получать http-запросы и выполнять в соответствии с этими запросами определенные действия, например запускать приложения и генерировать документы.

Документ, доступный через Web, называют Web-страницей, а группы страниц, объединенные общей темой и навигационно, — Web-узлами, или Web-сайтами. Один аппаратный Web-сервер может содержать несколько Web-сайтов, но возможна и обратная ситуация, когда огромный Web-сайт может поддерживаться группой Web-серверов (компьютеров).

Для того чтобы лучше понять идею организации Всемирной паутины, обратимся к рис. 2 , на котором показан пример использования WWW для поиска информации о новостях. Предположим, что пользователю, проживающему в США, необходимо узнать последние московские новости, и он не знает адреса сервера, на котором можно найти эту информацию. Вполне вероятно, что для того, чтобы получить необходимые данные, он набирает известный ему адрес Web-сайта, который физически расположен на компьютере в США и посвящен теме «Новости в мире». Очевидно, что на одном сервере не могут храниться данные о местных новостях всех уголков земного шара. При этом возможно, что у наиболее важных новостей мирового значения на сервере есть ссылки на новостные сайты, актуальные для разных регионов. Вполне вероятно, что, выбрав ссылку «Европа», пользователь соединится уже с другим компьютером, расположенным где-то в Европе (рис. 2). Предположим, что на странице европейского сайта есть ссылка на Россию. По ссылке «Россия» можно соединиться с сервером в России. Вероятно, по ссылке «Москва» на этом сайте пользователь получит необходимую информацию, а возможно, соединится с четвертым сервером, который представит необходимую ему информацию. Таким образом, уточняя и детализируя информацию, можно получить новости конкретного района. Важно отметить, что в представленном на рисунке примере пользователь обращается с запросами к разным серверам и при переходе с одного сервера на другой ему не нужно каждый раз задавать адреса серверов и тем более знать о том, где они физически находятся. В этом случае говорят, что процедура происходит прозрачно для пользователя, то есть пользователь воспринимает весь процесс так, как если бы все полученные им страницы находились на его собственном компьютере. Таким образом, процесс просмотра информации можно сравнить с перелистыванием страниц огромной книги на одном рабочем столе по принципу «нажми и получи». Процесс перемещения по документам с помощью гипертекстовых ссылок получил в обиходе название навигации, или серфинга .

Тот факт, что серфинг не требует знаний о местоположении искомых документов, как раз и является основным удобством и причиной популярности службы WWW.

Браузеры

ак мы уже отмечали, в браузерах реализованы две основные функции: запрос информации у Web-сервера и отображение ее на клиентском компьютере. Кроме того, браузеры обладают дополнительными сервисными функциями, такими как упрощение поиска, хранение закладок, указывающих на избранные страницы, и др.

Во многом развитие браузеров определялось конкуренцией двух компаний-разработчиков — Netscape и Microsoft.

В середине 1990-х годов компания Netscape захватила большую долю рынка благодаря своему продукту Netscape Navigator, а Microsoft начала активно продвигать разработанный ею Internet Explorer. История противоборства этих двух программ получила название войны браузеров, которая фактически свелась к появлению у них новых возможностей. Благодаря интеграции Internet Explorer с операционной системой Windows и предложению браузера в качестве бесплатной программы, Microsoft удалось одержать победу в этой войне. В результате рынок браузеров стал достаточно специфичным: сегодня наиболее популярные программы Internet Explorer и Netscape Navigator распространяются бесплатно, в то время как некоторые альтернативные и значительно менее распространенные программы являются платными.

Постепенно браузеры из устройств для просмотра HTTP-документов стали универсальными Интернет-клиентами. Более подробно о работе браузеров мы поговорим после того, как расскажем о строении Web-страницы.

Web-страница

опулярность WWW обусловлена тем, что можно не только просматривать чужие страницы и иметь доступ к огромному количеству информации, представленной на сотнях миллионов компьютеров, но и создать собственные ресурсы и таким образом донести любую информацию до всех будущих посетителей сайта. Иными словами, WWW — это глобальный механизм обмена информацией: одни люди помещают информацию на Web-серверы, а другие ее просматривают. Создав Web-сайт, владелец может поместить туда различного рода информацию: текст, графику, звук, анимацию, которая станет доступной для всех посетителей этого ресурса. С появлением в Сети вашей страницы информация о вас или о вашей фирме станет доступна сотням миллионов пользователей круглосуточно семь дней в неделю. Количество информации, которое может быть предоставлено посетителю, практически не ограничено по времени, в отличие от радио или телевидения. Для того чтобы ваш сайт был наиболее посещаемым, необходимо обеспечить быстрый доступ к нему. Если вы попытаетесь создать Web-сайт на домашнем компьютере, подключив его к Интернету через обычный модем и телефонную линию, вы не сможете обеспечить к нему быстрый доступ и, скорее всего, отпугнете потенциальных посетителей. Как показывает опыт, больше всего посетителей раздражает долгая загрузка страницы, поэтому сервер, на котором вы хотите разместить свой сайт, должен иметь высокоскоростное подключение к Интернету.

Для того чтобы обеспечить надлежащую скорость доступа к вашему ресурсу, желательно воспользоваться услугами так называемого провайдера хостинга. Хостинг (от англ. host — хозяин) — это предоставление качественной услуги по размещению сайта на физическом Web-сервере провайдера или собственном сервере, размещенном на площадке провайдера. Обычно хостинг-провайдер взимает плату, которая тем выше, чем больше арендуемое дисковое пространство и интенсивность трафика. Однако существуют и бесплатные услуги хостинга. Если вы захотите получить доменное имя третьего уровня (например, www.ivanov.narod.ru: (доменное имя первого уровня — ru, доменное имя второго уровня — narod, доменное имя третьего уровня — ivanov), то, скорее всего, это будет бесплатно. Доменные имена третьего уровня предоставляются многими компаниями, предлагающими бесплатный «народный» хостинг. Например, имя www.your-name.narod.ru (где your-name — это имя, которое вы можете дать своему ресурсу) предоставляет компания Яндекс. Однако солиднее иметь домен второго уровня — лучше всего подойдет имя вида «ваша _фамилия.ru или ваша_компания.ru». В этом случае вам придется как минимум оплатить регистрацию вашего доменного имени. Зато при наличии у вас подобного имени ваши коллеги смогут найти вас в Интернете, даже не зная точного имени вашего сайта. Например, сайт можно легко найти просто по названию журнала. При этом следует отметить, что сегодня найти незанятый домен довольно сложно.

Если вы собираетесь создать небольшой любительский сайт, то вас, скорее всего, устроит доменное имя третьего уровня и проблем с его бесплатным размещением не будет. Основные проблемы возникнут при его разработке.

Говорить о создании собственных страниц не имеет смысла до тех пор, пока мы не рассмотрим их устройство. Поэтому далее мы расскажем, из чего состоят Web-страницы, и для начала поговорим об основах языка гипертекстовой разметки HTML (Hypertext Markup Language), который предназначен для создания гипертекстовых документов.

HTML

Предыдущих публикациях настоящего цикла мы уже отмечали, что к Интернету подключается огромное количество компьютеров различной архитектуры и разных возможностей по отображению информации. Задача разработки страниц для каждого типа оборудования является практически невыполнимой. С учетом того, что документ будет доступен миллионам компьютеров, нельзя заранее определить, на каком типе оборудования он будет воспроизводиться. Если мы говорим о текстовом документе, то он может отображаться не только на различных типах экранов, но и, например, может быть воспроизведен программой синтеза речи. При этом функциональная разметка документа должна быть прочитана независимо от способа вывода.

Вместо того чтобы указывать, как должен выводиться документ на том или ином оборудовании, разработчики пошли иным путем: предложили использовать специальный язык функциональной разметки — HTML. HTML-документ состоит из собственно текста и разметки, к которой относятся все записи, не являющиеся информационным наполнением документа. Разметка HTML позволяет определить ссылки на внешние документы или на внутренние разделы того же самого документа, а также несет информацию о форматировании документа.

Для того чтобы пояснить идею организации HTML-документа, уместно привести аналогию с работой технического редактора, который готовит текст для верстки. Редактор делает разметку текста, отмечая, каким должен быть формат, как набрать заголовки, где что расположить. Например, это могут быть пометки типа: «Данный абзац напечатать жирным шрифтом, такое-то предложение выделить красным цветом, а после такого-то абзаца вставить текст со страницы такой-то». Для того чтобы комментарии редактора читались корректно, существуют специальные правила разметки. Верстальщик читает комментарии технического редактора и заверстывает текст в соответствии с ними.

Аналогичные комментарии записываются в HTML-документе, затем они прочитываются браузером, чтобы он «знал», как нужно отображать данные на экране компьютера. Язык HTML был разработан в конце 1980-х годов в физической лаборатории CERN (Швейцария) и поначалу использовался в локальной сети лаборатории. Однако вскоре он завоевал популярность и стал широко применяться в Интернете.

Следует отметить, что понятие функциональной разметки шире, чем понятие форматирования документа. Например, гипертекстовая разметка дает возможность определить, что тот или иной текст в документе является названием страницы (title). Очевидно, что это уже не форматирование, а именно определение функциональности конкретной части документа.

HTML описывает лишь самые общие инструкции для представления информации, которые могут быть интерпретированы различными браузерами на разных платформах. При этом изначально принимается как данность факт невозможности достижения абсолютной точности воспроизведения исходного документа всеми клиентами.

Это означает, что страница, описанная одним и тем же HTML-кодом, может по-разному отражаться на двух компьютерах с разными платформами, режимами монитора и браузерами. Можно сказать, что браузер выполняет форматирование документа, исходя из набора инструкций, содержащихся в HTML, и из возможностей по отображению информации конкретным компьютером.

Например, если на вашем компьютере нет шрифта, которым предписывается отобразить ту или иную надпись, будет использован другой, ближайший к нему из доступного набора.

Кроме того, пользователи могут изменить настройки браузера так, чтобы документ отображался оптимальным для них образом.

Например, в настройках браузера вы можете указать правила выбора цвета для отображения фона документа, определив, каким должен быть цвет шрифта на Web-странице и каким цветом должны выделяться текстовые гиперссылки.

Команды HTML (или управляющие маркеры гипертекстового документа) называют тэгами (от англ. tag — ярлык, маркер), они вставляются непосредственно в текст документа и заключаются в угловые скобки <...>.

Унифицированный набор заранее определенных тэгов позволяет пользоваться различными браузерами. Несмотря на тот факт, что HTML используется для представления Web-страниц, он также может применяться и для других целей, например для представления документов, размещенных на CD-ROM.

Основное достоинство HTML — это его простота. Для подготовки HTML-документов не требуется знания языков программирования. Добавлять в документ тэги разметки можно, используя обычный текстовый редактор или особые HTML-редакторы, имеющие специальные элементы управления для упрощения ввода тэгов.

Наличие средств визуальной разработки Web-страниц позволяет создавать HTML-документы, даже не запоминая назначения тех или иных тэгов. Визуальной разработкой называется процесс, при котором пользователь оперирует объектами, которые при разработке выглядят почти так же, как и при отображении браузером, а HTML-код создается при этом автоматически.

Существует более сотни тэгов для разметки информации на Web-странице. Большинство тэгов используется в парах. Открывающий и закрывающий тэги начинаются и завершаются знаками < и >. Закрывающий тэг отличается от открывающего наличием символа / (слэш) перед ключевым словом. Например, пара тэгов (см. таблицу) используется для того, чтобы дать команду браузеру, что текст, помещенный между тэгами, должен быть отображен жирным шрифтом, а тэги показывают, что при отображении текста должен быть применен курсив. Открывающий и закрывающий тэги воздействуют на часть документа, заключенную между ними. Расположение парных тэгов выполняется так, чтобы соблюдались правила вложения.

Кроме парных, бывают непарные тэги, которые определяют разовый эффект в конкретном месте или оказывают воздействие на весь документ. Например, тэг
часто используется для обозначения необходимости разрыва строки.

Эффект применения тэга может видоизменяться путем добавления атрибутов. Атрибут (от лат. attributum — присоединенное) показывает признак объекта, определяющий его состояние. Применение некоторых атрибутов подразумевает указание значения атрибута, которое отделяется от ключевого слова атрибута знаком равенства и заключается в кавычки.

Тэг присваивания цвета тексту (в таблице он показан в третьей строке) является примером тэга с атрибутом.

Одним из важнейших является тэг, определяющий гиперссылки. При определении гиперссылки необходимо связать элемент Web-страницы, по которому будет происходить переход, с адресом данного перехода. Тэг обозначается по первой букве слова «anchored», что в переводе с английского означает «привязанный».

Адрес перехода определяется значением атрибута Href и представляет собой URL того ресурса, на который указывает ссылка. Таким образом, формат определения гиперссылки можно представить в виде:

HTML-документ начинается с тэгов (название страницы, указание кодовой страницы, указание типа документа) и заканчивается тэгами . Почти все наполнение, которое вы хотите включить в страницу, помещается между тэгами и .

Стандарт HTML — это набор формальных рекомендаций, определенных консорциумом W3C (World Wide Web Consortium) и обрабатываемых браузерами ведущих производителей, такими как Microsoft Internet Explorer и Netscape Navigator. Последний стандарт языка — это HTML 4.0. Однако Internet Explorer и Netscape Navigator интерпретируют отдельные конструкции языка по-разному, а также используют некоторые нестандартные расширения, специфические только для данного браузера. Поэтому, в принципе, нет гарантии, что отображение страниц, использующих расширенные возможности HTML, будет одинаково осуществлено в разных браузерах. В связи с этим разработчики Web-страниц вынуждены проверять функциональность создаваемых сайтов как минимум в двух вышеназванных браузерах.

Механизм работы Web-сервера

осле того как мы ввели понятие языка HTML, можно подробнее описать механизм работы Web-сервера и браузера. Рассмотрим пример.

Предположим, ваш товарищ создал свой сайт по адресу www.petrov.ru и расположил на нем свое резюме по адресу http://www.petrov.ru/resume.htm. Что происходит, когда вы просматриваете данное резюме со своего компьютера?

Как только вы набираете в своем браузере вышеуказанный URL, браузер получает информацию об используемом протоколе (http), имени сервера (www.petrov.ru) и запрашиваемом файле (resume.htm). Браузер обращается к DNS-серверу, чтобы перевести имя сервера www.petrov.ru в IP-адрес, который служит для нахождения нужного сервера, устанавливает связь с Web-сервером и, используя протокол http, запрашивает искомый ресурс. Сервер посылает браузеру HTML-страницу, чтобы он мог отобразить данный документ. Браузер считывает HTML-тэги, воссоздает страницу на экране вашего компьютера, и вы видите результат своего запроса.

Обычно даже простая Web-страница содержит не только текст, но и графику. Иными словами, страница состоит из нескольких файлов, то есть в общем случае передаваемый на ваш компьютер файл может быть не только текстовым, но и графическим или еще каким-либо. Как же браузер распознает эти файлы? Вначале сервер посылает текстовое сообщение, которое информирует клиента о том, какой файл он будет отправлять: что это будет — текст в формате HTML, или графика в формате jpg, или что-нибудь другое, и только после этого передает содержание данного файла. Несмотря на то что обычно Web-страница состоит из многих файлов, за время одного запроса Web-сервер посылает только один файл. То есть, получив HTML-текст и найдя в нем, например, ссылку на графический элемент, браузер посылает новый запрос на сервер, и при этом не обязательно на тот же самый, с которого пришел HTML-текст. Вероятно, большинству пользователей Интернета знакома ситуация, когда загрузка страницы происходит с задержкой и вначале отображается текст, а потом начинают появляться картинки. Данная ситуация как раз отражает последовательность загрузки элементов Web-страницы. Для того чтобы скачать каждый новый файл, браузер должен установить новую сессию. При этом, поскольку современные серверы и браузеры работают в многопоточном режиме, одновременно могут выполняться несколько сессий, но для скачивания каждого нового файла инициируется своя сессия.

Если запрашиваемого ресурса по данному адресу нет, то Web-сервер выдаст сообщение, которое вы, вероятно, не раз видели на своем экране: 404/File not found (файл не найден).

Статические и динамические страницы

татические страницы представляют собой точную копию файлов, лежащих в каталогах Web-cервера, и не изменяются до тех пор, пока разработчик сам в них что-то не поменяет. Однако страницы могут формироваться динамически, то есть во время обработки запроса по какой-то программе, а не из готового файла на диске. Существует несколько способов формирования такой страницы:

  • формирование по запросу непосредственно на Web-сервере. Для реализации возможности динамического формирования Web-страниц необходимо дать серверу указания, какие файлы являются «обычными», а какие содержат инструкции по их программной обработке. Так, все файлы в соответствующем каталоге Web-сайта, в списке прав доступа к которым есть «выполнение», считаются динамическими, а сервер сам подбирает средство для формирования конкретной страницы при обращении к такому файлу на основе его атрибута и/или расширения его имени. При этом страницу может сформировать либо сам сервер (при помощи специальных команд), либо внешняя программа, запускаемая непосредственно или через CGI-интерфейс (common gateway interface — общий шлюзовой интерфейс). Программа для формирования динамической страницы может быть написана на компилируемом или интерпретируемом языке. Текст программы, содержащий команды для динамического формирования страниц, называется скриптом. Список соответствия атрибутов скриптов внешним программам для их обработки задается в разделе Web-сервер/Обработчики скриптов. Например, по умолчанию скрипты с расширениями *.pl и *.cgi обрабатываются интерпретатором языка Perl;
  • формирование на компьютере пользователя. В этом случае тексты программ для формирования динамических Web-страниц передаются сначала на локальный компьютер пользователя, где уже браузер должен вызвать для них соответствующее средство для обработки и получения Web-страницы. Программа для формирования динамической страницы также может быть написана как на компилируемом, так и на интерпретируемом языке.

Технология CGI

Вы наверняка сталкивались со страницами, которых ранее не существовало и которые были созданы по вашему запросу динамически — сформированы, как говорится, «на лету».

Например, любая книга отзывов предоставляет вам определенную форму, в которую вы добавляете свой отзыв, и затем, когда вы в следующий раз откроете эту страницу, она будет содержать новое сообщение.

Одна из технологий, позволяющая добавить динамическое содержание в Web-страницы, называется CGI. Она позволяет ассоциировать с тем или иным URL не просто статический документ, а программу, в результате работы которой могут быть сформированы данные в реальном времени.

Рассмотрим пример с предоставлением сведений о погоде. Метеорологическая сводка о погоде меняется каждый день, и ежедневно может создаваться новая статическая страница с прогнозом. Однако, если вы хотите предоставлять мгновенные данные, вы должны каждый раз генерировать новую страницу. Это может быть реализовано на основе CGI-технологии. В момент обращения на сервер на нем запускается CGI-программа, которая обращается к цифровому измерительному устройству и выдает сведения о температуре, давлении и т.д. Когда вы в очередной раз обратитесь на этот адрес, вы получите новые сведения.

Другой пример: когда вы заполняете некоторый запрос, например запрос в поисковой системе, то в ответ получаете результаты работы СGI-программы в виде набора искомых адресов.

CGI-программу можно представить как часть Web-сервера, которая запускается Web-сервером в реальном времени. Сервер передает запросы пользователя CGI-программе, которая их обрабатывает и возвращает результаты своей работы на экран пользователя (рис. 3). На большинстве Web-серверов CGI-механизм организован следующим образом: создается специальная поддиректория, в которой хранятся подобные программы, и администратор Web-сервера настраивает доступ к ней таким образом, чтобы файлы из нее не считывались, а запускались на выполнение. Результат работы программы отсылается браузеру в ответ на запрос. С точки зрения клиента нет никакой разницы, что находится по адресу данного URL — статический документ или CGI-программа. Браузер воспринимает информацию одинаково независимо от того, сформирована ли она «на лету» или речь идет о статической странице. Результат работы CGI-программы имеет тот же формат, что и статический документ.

Аббревиатура CGI наверняка попадалась вам в строке вашего браузера во время путешествия по Всемирной паутине, и вы, скорее всего, видели ссылку на /cgi-bin/ — директорию, в которой обычно и лежат cgi-программы. Множество интерактивных сервисов, таких как гостевая книга, форум и т.д., построены именно на cgi-программах.

Под термином «CGI» понимают не только программу, но и протокол. В этом смысле CGI — это стандартный для Web-сервера способ передать пользовательский запрос прикладной программе и получить данные назад для передачи их пользователю. Протокол CGI для пересылки данных между сервером и приложением является частью протокола HTTP.

Следует отметить, что если вы собираетесь разместить свою страницу на серверах бесплатного хостинга, то вполне возможно, что cgi-скрипты на этих серверах не поддерживаются.

Альтернативой CGI является технология компании Microsoft Active Server Page (ASP), построенная по тому же принципу: скрипт, включенный в Web-страницу, выполняется на сервере до того, как страница отсылается пользователю.

Существуют и другие технологии, работающие по тому же принципу.