    ГЛАВА     28 

    Создание приложений для Web-сервера 

    хочу дать вам совет: никому не говорите, что вы читали эту главу. Если вы 
сделаете подобную глупость, каждый узнавший, что вы что-то в этом смыслите, 
начнет донимать вас вопросами. Все что-то слышали о WWW и его возможностях, но 
только члены клана Web-мастеров имеют точные сведения о технологиях Internet. 
    Некоторые из вас настолько безрассудны, что даже не боятся сообщить своему 
боссу, встретившись с ним в кафе за чашкой чая (и желая придать себе вес в его 
глазах), что на днях изучили возможности работы с Internet в последней версии 
Delphi. После этого вам придается решать, как выполнить задание шефа и 
закончить к концу квартала основательное Internet-приложение для заграничных 
продаж, если ваша фирма даже не имеет Web-сервера... 
    Однако шутки в сторону. Расширения сервера (server-side extension) — это 
просто приложения IS API, представляющие собой DLL, получающие определенные 
параметры на входе, обрабатывающие их и возвращающие строки информации. 

    ПРЕДОСТЕРЕЖЕНИЕ 

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

    Создание приложения для построения статических HTML-страниц 

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

    Расширение приложения для создания динамических страниц 

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

    Добавление соединений с базами данных 

    Включение данных элемента TLabel и TQuery в HTML-страницу. 

660


    На заметку 

    Если у вас нет WWW-сервера или броузера, это еще не причина для паники. У 
вас уже может быть и то, и другое, просто вы об этом не подозреваете. Windows 
NT 4.0 Workstation поставляется с Peer Web Service и Internet Explorer (IE). 
IE— это и есть WWW-броузер, a Peer Web Server представляет собой 
ISAPI-совместщый^едв5р_в комплекте с серверами FTP'и Gopher. WWW-броузеры и 
серверы можно получить из Internet или служб наподобж.^отрцЗе^уе^^^ 
    Вы можете использовать компоненты Cljentjmd ServerWinsock 
Socket.УС1.15,Пе1в1и,3„для построения своих собственных^ сервера и броузера. 
Вы можете также использовать управляющие элементы ActiveX для ускорения 
разработки броузера. 

    Подготовка к разработке приложений для Web-сервера 

    Прежде чем приступить к работе с Delphi, необходимо пройти краткий курс 
"хороших манер" для понимания, по крайней мере, терминологии, используемой в 
этой главе. Вот основные понятия. 
    •   HTTP. Аббревиатура от Hypertext Transfer Protocol (протокол передачи 
гипертекста) — названия протокола для передачи данных по Internet. 
    •   HTML. Аббревиатура от Hypertext Markup Language (язык разметки 
гипертекста), подмножества SGML (Standard Generalized Markup Language). 
Используется для описания форматирования текста набором дескрипторов. 
    •   URI и URL. Universal Resource Identifier/Locator (универсальный 
идентификатор/локатор ресурса). Используется для идентификации какого-либо 
объекта в Internet. 
    •   CGI. Common Gate-way Interface (Стандартный интерфейс шлюза) был 
первой попыткой интеграции, WWW-серверов и отдельных программ; программы CGI 
могут компилироваться программами или сценариями. 
    •   Win-CGI. Windows-вариант CGI. 
    •   Web scripting languages. Языки сценариев Web включают языки Java, 
JavaScript, J Script и VBScript, но не ограничены ими. 
    •   ActiveX. О технологии ActiveX рассказывается в главе 21, "Создание 
элементов управления ActiveX". 
    •   ISAPI. Стандарт Internet Server API изначально был создан как 
Microsoft Information Server API, но в дальнейшем был предложен в 
качестве^открытого стандарта.	"~      ' 
    В   NSAPI. Стандарт Netscape Server API используется для взаимодействия с 
серверами компании Netscape. 
    Вряд ли стоит изучать два различных стандарта API, тем более что во время 
написания этой книги компания Netscape собиралась принять стандарт ISAPI. 

    Intranet 

    Большинство людей, знающих, что такое Internet, не совсем понимают 
значение термина intranet. Его можно определить как сетевую среду 
ограниченного масштаба. 
    Почти все фирмы сегодня имеют корпоративные локальные и глобальные 
вычислительные сети, и intranet — просто расширение таких сетей с 
использованием стандартов, разработанных для Internet. Есть и такая точка 
зрения: intranet— это использование Internet-технологий в локальных сетях, a 
extranet— использование Internet-технологий в глобальных сетях. 

    НИР и HTML 

    HTTP означает Hypertext Transfer Protocol (протокол передачи гипертекста), 
a HTML — Hypertext Markup Language (язык разметки гипертекста). Схожесть 
аббревиатур приводит к ошибочному мнению, что это синонимы, однако для 
программиста должно быть ясно, что понятия язык и протокол описывают 
совершенно разные концепции. 
    HTTP — протокол уровня приложения, работающий поверх протокола TPC/IP 
(Transmission Control Protocol/Internet Protocol — протокол управления 
передачей данных/протокол Internet). HTTP — лишь один из многих протоколов, 
работающий поверх TCP/IP. Другие примеры таких протоколов — File Transfer 
/VotocorTJFTP), Post Office Protocol (POP), Simple Mail Transfer Protocol 
(SMTP). Назначение HTTP — передача данных, которые могут быть представлены в 
различ

    Глава 28. Создание приложений для Web-cepeepa 661 

    ных формах. Наиболее популярная форма — текстовые данные, форматированные 
в соответствии с требованиями HTML. Протокол HTTP предназначен не только для 
передачи HTML-документов; он может передавать графическую, видео- и 
аудиоинформацию и другие типы информации. 
    HTML использует набор дескрипторов для описания форматирования текста. 
Например, текст между дескрипторами <Н1> и </Н1> должен трактоваться как 
заголовок первого уровня, а текст между <В> и </В> должен выводиться 
полужирным шрифтом. 
    Какое отношение все это имеет к вашим приложениям для Web-сервера? 
Во-первых, ваше приложение будет использовать описанные стандарты для ввода 
данных и представления вывода. Во-вторых, знание этих концепций позволит 
создавать приложения, которые не будут ограничены приземленным миром ASCII-текстов. 

    Еще немного об HTTP и HTML 

    Из-за ограниченного объема главы и огромного количества информации на эту 
тему, я не буду вдаваться в детали HTTP и HTML. Если вы не знакомы с ними, я 
расскажу о самых важных вопросах. 

    HTTP 

    Знание особенностей протокола HTTP позволит расширить возможности 
приложений, которые будут описаны в этой главе. Это несложно, особенно если 
учесть, что HTTP версии 1.0 (в завершенном виде описан в RFC 1945) 
поддерживает всего три метода: 
    •    GET (используется для получения объекта, определенного с помощью URL); 
    •    HEAD (используется для запроса заголовочной информации об объекте, в 
отличие от GET, который запрашивает и заголовок, и содержимое объекта); 
    •    POST (запрос на прием сервером информации от клиента). HTML 
    Изучение HTML для программиста в Delphi не представляет никакой сложности. 
Количество дескрипторов HTML куда меньше, чем количество зарезервированных 
слов, функций, методов и свойств, с которыми вы работаете в Delphi. 
    Простейший способ изучить основы HTML— просмотреть исходные тексты 
существующих HTML-страниц. Большинство WWW-броузеров позволяет сделать это. 
    Главное, что следует понять, — это то, что дескрипторы описывают 
представление текста. 
    Например, <Hl>welcome to My Home Page</Hl> сообщает броузеру, что он 
должен показать текст Welcome to My Home page как заголовок первого уровня, но 
как именно будет показан заголовок, каким шрифтом, цветом и т.д., зависит от броузера! 
    За детальной информацией обратитесь по адресу http://www.w3.org начальной 
страницы World Wide Web Consortium (W3C). 

    Web-броузер как интерфейс пользователя 

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

    ActiveX 

    Интерфейс ActiveX более гибок и универсален по сравнению с HTML. 
Использование этой технологии предоставляет возможность создания интерфейса, 
который ближе к обычному GUI-интерфейсу стандартного приложения, чем HTML. 

    Языки программирования/сценарии Web 

    Вы можете удивиться: зачем программисту Delphi знания о языках 
программирования и сценариях Web? Хотя Delphi и превосходный язык для создания 
автономных программ, он бесполезен, когда надо обеспечить управление выводом 
текста документов в WWW-броузере. HTML предоставляет вам основные средства для 
вывода форматированного текста 

    662 Часть VI. Сложный материал 

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

    API-серверы 

    Хотя стандарт NSAPI (Netscape-версия API-сервера) был создан до ISAPI, 
компания Netscape решила придерживаться стандарта ISAPI. По-моему, это 
совершенно верное решение, и в этой главе мы рассмотрим только стандарт ISAPI. 
    Идя навстречу программистам, Borland поставляет DLL-переводчики стандартов 
ISAPI и NSAPI. Разработчикам программного обеспечения не придется 
создаватьГдва варианта своих приложений!     ' 
    Стандарт ISAPI недавно был представлен в качестве открытого стандарта 
группы W3C, а потому получить докумен-T^miiojTojejvryjaaejab легко (я, 
например, получил ее с узлов Microsoft и W3C). В этой главе основное ^нимание 
уделяется не описанию стандарта ISAPI, а его использованию для разработки 
приложений". ~	~ ~~ 

    Большая Тройка 

    Дальше в этой главе рассказывается о создании DLL, удовлетворяющих 
стандарту ISAPI. Когда вы будете создавать первую DLL в следующем же примере, 
то увидите диалоговое окно New Web Application, в котором выберите ISAPI/NSAPI 
Dynamic Link Library. Вы можете также выбрать CGI или_\Л/[п-СС1_— .создание 
любых типов приложений практически одинаково с точки зрения раЭр!абатчика."~~"""~ 

    Использование Delphi для разработки ISAPI DLL 

    Сейчас, когда я пишу эти строки, ISAPI-расширения де-факто являются 
стандартом в мире Windows. Поскольку вы программируете в Delphi, можете 
совершенно спокойно считать, что вы создаете приложения для работы под 
Windows, и использовать стандарт ISAPI, который принят в настоящий момент и 
Microsoft, и Netscape, так что у вас не должно возникнуть никаких проблем. 
    К этому моменту вы уже должны понимать концепцию программирования 
Web-приложений. Поэтому воспользуемся предоставляемым Delphi инструментарием 
для создания DLL, ^<ото?ая будет отвечать на запросы клиентов созданием. 
корректних,111МЬ<траниц. Сначала рассмотрим создание расширения сервера, 
которое возвращает каждый раз одну и ту же страницу независимо от запроса 
(естественно, просто с целью обучения и показа механизмов работы приложения 
Web-сервера по сравнению со стандартным процессом запрос-ответ HTTP-сервера). 

    Статическая HTML-страница 

    Создание DLL по стандарту ISAPI похоже на разработку любой стандартной 
DLL. Для этого выполните следующие действия. 
    1.   Выберите команду File^New, и откроется диалоговое окно New Items, 
показанное на рис. 28.1. 
    2.   Щелкните на пиктограмме Web Server Application, а затем на кнопке ОК. 
После этого появится диалоговое окно New Web Server Application, показанное на 
рис. 28.2. 
    3.   Опция ISAPI/NSAPI Dynamic Link Library выбрана по умолчанию, поэтому 
просто щелкните на кнопке ОК. 
    Теперь вы попадаете в рабочую среду для разработки ISAPI-расширения 
сервера. Обратите внимание, что в вашем проекте содержится специальный модуль 
WebModule (рис. 28.3), не очень отличающийся от стандартного DataModule,. Он 
позволяет помещать в него различные компоненты и обеспечивает интерактивную 
работу с ними. Как вы увидите позже, это относится и к компонентам баз данных. 
    Точно так же, как вы разрабатываете обычную DLL, экспортирующую некоторые 
функции, вы разрабатываете и ISAPI-DLL сиспрльзрванием WebDispatcher Actjpnltems. 
    Каждый WebModule содержит диспетчер по умолчанию, который может быть 
представлен в виде постового, регулирующего движение в вашем приложении. 
ТШсды"й~раТпрй запросе DLL вашим Web-броузером диспетчер определяет, какой 
именно получен запрос и какие действия по его обработке должны быть выполнены. 
Рассмотрим работу диспетчера на примере приложения, возвращающего статическую 
HTML-страницу.	~ "~ 

    Глава 28. Создание приложений для Web-cepeepa	663 

    Для создания обработчика (Actionltem) следует вызвать редактора Action 
Editor. Как и большинство редакторов свойств, его можно вызвать различными путями. 
    •   Дважды щелкнуть в окне WebModule. 
    •   Щелкнуть в окне WebModule правой кнопкой мыши и выбрать в контекстном 
меню команду Action Editor. 
    Рис. 28.1. Диалоговое окно New Items После вызова редактора Action Editor 
выполните следующие действия. 
    1.   Щелкните на кнопке Add для создания первого элемента Actionltem. 
    2.   Щелкните на элементе Actionltem (WebActionlteml) в редакторе для его 
выбора. После этого его свойства можно редактировать в окне Object Inspector. 
    3.   Присвойте созданному объекту подходящее имя, например aiStatic. 
    4.   Свяжите объект с URI, введя /HelloWorld в поле свойства Pathlnf о. 
    После выполнения последнего пункта ваш проект будет выглядеть примерно 
так, как на рис. 28.4. 

    Рис. 28.2. Диалоговое окно New Web Server Application 


    664 Часть VI. Сложный материал 


    Рис. 28.3. Заготовка приложения для Web-сервера с пустым модулем WebModule 

    Рис. 28.4. Использование редактора Action Editor и инспектора объектов 


    Глава 28. Создание приложений для Web-cepeepa 665 

    Назначение URI объекту чем-то похоже на присвоение имени методу или 
проекту. Кстати, пора уже дать имя вашему проекту, которое одновременно будет 
определять и имя вашей DLL. Выполните следующие действия. 
    1.   Сохраните проект под именем WEBDEMO.DPR (ваша ISAPI-DLL будет иметь 
имя \VEBDEMO.DLL). 
    2.   Напишите код для объекта, для чего выберите вкладку Events в окне 
Object Inspector. Вы увидите, что обрабатывается только одно событие вашего 
объекта— OnAction.	—.-.._. 
    3.   Дважды щелкните на нем для создания заготовки процедуры обработки 
события. Delphi сгенерирует заготовку в следующем виде. 

    procedure TWebModulel.WewbModulelActionsOAction   (Sender:   TObject; 
    Request:   TWebRequest;   Response:   TWebResponce;   var Handled:   
Boolean); begin 
    end; 

    He волнуйтесь по поводу большого числа параметров процедуры — при создании 
статической HTML-страницы вам из всего этого богатства понадобится только один 
параметр— Response. Вы используете объект TWebResponce для возврата вашей 
статической страницы (этой цели служит его свойство Content). Вы помните, что 
HTTP-сервер отвечает на запрос броузера двумя объектами — заголовком и 
содержимым? Заголовок будет создан Delphi самостоятельно, по умолчанию, и 
беспокоиться о нем вам не надо; позаботьтесь только о Response. Content. Это 
строковая переменная, и все, что от вас требуется, — поместить в нее текст 
своей страницы. 
    Вот пример кода, который вы можете поместить в обработчик. 

    procedure  TWebModulel.WewbModulelActionsOAction   (Sender:   TObject; 
    Request:   TWebRequest;   Response:   TWebResponce;   var Handled:   
Boolean); var HTML:   string; begin 
    // В следующих строках используются  стандартные 
    //  дескрипторы HTML. 
    HTML     =	'<HTML>'; 
    HTML     =  HTML  +   '<BODY>'; 
    HTML     =  HTML  +   '<Hl>Hello  World Wide  Web</Hl>'; 
    HTML     =  HTML  +   '<P>This   is   an  example  of  a'   + '   static  
HTML page.</P>'; 
    HTML     =  HTML  +   '</BODY>'; 
    HTML     =  HTML   +   '</HTML>; 
    Response.Content   :=  HTML; end; 

    Итак, примите мои поздравления: ваше первое приложение для Web-сервера 
готово! Скомпилируйте его. Если вы знаете, как его протестировать, пропустите 
следующий раздел и следуйте дальше, если же вам нужна помощь в тестировании, 
загляните в следующий раздел. 

    Тестирование и распространение ISAPI-DLL 

    Как вы уже знаете, ISAPI-DLL может работать только с ограниченным числом 
Windows WWW-серверов, и для использования (и тестирования) DLL надо иметь 
именно такой сервер. Если вы используете подобный сервер, по всей вероятности, 
при установке был создан специальный каталог для такого рода динамических 
библиотекЛЕсли ваш сервер — Microsoft Personal We 
    b Server for Windows 95, то соответствующий каталог— scripts. В противном 
случае вам придется порыться в документации к вашему серверу и узнать, где 
именно находится каталог для ISAPI-DLL. Поместив результат вашего творчества в 
нужный каталог, выясните URL для вызова действия (Actionltem). Это очень 
просто. Допустим, ваш сервер — http://www.server.com, каталог для DLL— scripts 
в корневом каталоге сервера. Тогда URL будет выглядеть как http: //www. 
server.com/scripts/WebDemo.dll/HelloWorld; результат просмотра показан на рис. 28.5. 

    Динамическая HTML-страница 

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

    666	Часть VI. Сложный материал 


    Рис. 28.5. Результат вызова ISAPI-DLL в броузере Microsoft Internet 
Explorer Для вывода динамической страницы создайте объект Actionltem. 

    1.   Загрузите в проект WebDemo. 
    2.   Вызовите редактор Action Editor и добавьте еще один элемент Actionltem. 
    3.   Измените его имя на aiDynamic. а свойство Pathlnf о — на /DateTime. 
    4.   Дважды щелкните на событии OnAction объекта aiDynamics и добавьте 
приведенный ниже текст в обработчик события. 

    procedure  TWebModulel.WewbModulelActionslAction   (Sender:   TObject; 
    Request:   TWebRequest;   Response:   TWebResponce;   var  Handled:   
Boolean); var  HTML:   string; begin 
    //  В  следующих  строках используются  стандартные 
    //  дескрипторы HTML. 
    HTML     =	'<HTML>'; 
    HTML  = HTML + '<BODY>'; 
    HTML  = HTML + '<:Hl>The current Date and Time is...</Hl>'; 
    HTML  = HTML + DateTimeToStr(Now); 
    HTML  = HTML + '</BODY>'; 
    HTML  = HTML + '</HTML>; 
    Response.Content   :=  HTML; end; 

    Скомпилируйте и протестируйте DLL, не забывая, что следует изменить запрос 
для проверки работоспособности нового действия. URL будет выглядеть как http: 
//www.server.com/scripts/WebDemo.dll/DateTime; результат на экране броузера 
представлен на рис. 28.6. 
    Если вы перед этим запускали предыдущую версию DLL, может оказаться, что 
она все еще находится в памяти сервера. Как ее убрать оттуда, зависит от типа 
сервера, так что поищите информацию об этом в документации на сервер. 
Подсказка: перезапустите сервер, и это приведет к желаемому результату. 

    I Совет 1 


    Глава 28. Создание приложений для Web-cepeepa 667 


    Рис. 28.6. Страница с текущими временем и датой в броузере 


    Обработка ввода пользователя 

    Рассмотрим остальные параметры обработчика события OnAction, которые до 
сих пор нас не интересовали. Вот как выглядит обработчик. 

    procedure TWebModulel.WewbModulelActionslAction   (Sender:   TObject; 
    Request:   TWebRequest;   Response:   TWebResponce;   var  Handled:   
Boolean); var  HTML:   string; begin end; 

    Ввод пользователя передается с помощью параметра Request. Ниже перечислены 
основные свойства объекта TWebRequest. 

    Свойство	Описание 

    Query	Строка со всеми параметрами, полученными с помощью запроса GET_ 
    QueryFields	Разобранная форма Query 
    Content	Строка со всеми параметрами, полученными с помощью запроса POST 
    ContentFields	Разобранная форма Content 

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

    Методы GET и POST 

    GET и POST — эти методы, используемые HTTP-клиентами для запроса 
информации от HTTP-сервера. Не будем вдаваться в детали использования этих 
методов передачи информации и остановимся только на их применении в формах. 
    Отметим только, что метод GET несколько проще и в основном именно он 
используется в поисковых службах Internet. Фактически его использование 
сводится к тому, что при запросе после конца стандартного URL добавляется знак 
вопроса (?), за которым следуют пары имя=значение, разделенные амперсандами 
(&) (если в значении встречается пробел, он заменяется на (+)), т.е. URI может 
выглядеть примерно так: http: //www. server, com/search/results. 
dll?key=Delphi&subject= web+server+application. 

    668 Часть VI. Сложный материал 


    Использование HTML-форм 

    При вводе подобного 1Ж1_вручную неизбежно возникают ошибки набора, так что 
куда более простым и практичным путем будет испо^ПдЗование^^о^м: для создания 
таких URI "на ходу", во время работы. Не будем углубляться в мир HTML-форм и 
рассмотрим простой пример, который можете найти на дополнительно 
распространяемой дискете (листинг 28.1). 

    Листинг 28.1. \UDELPHI3\CHP28\FORM01. нтм. Web-страница с двумя формами ввода 

    <html> 
    <title>Web Server Applications</title> 
    <bodj>> 
    <hl align="center">Web Server Applications</hl> 
    <h2>Parsed HTML File</h2> 
    <p>This example shows how an ISAPI DLL is used to parse a standard HTML 
page and replace TCustomTags with data determined at run time.</p> 
    <p>To see this example, fill out the following form and submit.</p> 
    <hr> 
    <p>This   form uses   the  GET method</p> 
    <form action="../scripts/WebDemo.dll/ParseFile"  methpd="GET"> <p>Name:   
<input  type="text"   size="20"  name="Name"x/p> <p>Address:   <input  
type="text"   size="20"  name="Address"x/p> <p>Phone:   <input   type="text"   
size="20"   name="Phone"></p> <p>E-mail:   <input  type="text"   size="20"   
name="email"x/p> <p><input   type="submit"xinputtype="reset"x/p> </form> 
    <hr> 
    <p>This   form uses   the   POST  method</p> 
    <form  action="../scripts/WebDemo.dll/ParseFile"  method="POST"> <p>Name:  
 <input  type="text"   size="20"  name="Name"x/p> <p>Address:   <input   
type="text"   size="20"  name="Address"X/p> <p>Phone:   <input   type="text"   
size="20"   name="Phone"x/p> <p>E-mail:   <input   type="text"   size="20"   
name="email"x/p> <pxinput  type="submit"xinpu 
    t  type="reset"x/p> </form> 
    </body> </html> 

    В этом листинге содержатся две формы. Каждая из них заключена между 
дескрипторами <FORM> и </FORM>. В каждой форме по две кнопки — одна для 
повторной инициализации jJiopMbi (<INPUT TYPE = "reset">), вторая — для 
передачи запроса (<INPUT TYPE = "submit">). Когда вы щелкаете на ней, 
выполняются действия, которые и описаны в строке с дескриптором <FORM> 
(заметьте, что первая форма использует метод GET, а вторая — метод POST). 
    Когда страница загружается в броузер, она представляет несколько полей 
ввода с помощью дескрипторов <INPUT TYPE = "text">, каждое из которых имеет 
связанное с ним имя и значение, определяемое тем, что ввел пользователь. После 
того как пользователь щелкнет на кнопке передачи информации серверу, броузер 
создаст и отформатирует соответствующий URI. 

    Компонент TPageProducer 

    Настало время познакомиться с еще одним компонентом Delphi 3 для работы в 
Internet. Компонент TPageProducer поможет вам при создании динамических 
HTML-страниц из шаблонов. Он получает либо текстовый файл, либо объект Т 
String, разбирает его содержимое на специальные объекты ТТад и заменяет их 
определенными при выполнении программы данными. 

    Глава 28. Создание приложений для Web-cepeepa	669 

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

    ; Листинг 28.2. \UDELPHI3\CHP28\THANKYOU.HTM. Шаблон для страницы "Thank You" 

    <html> 
    <head> 
    <title>Thank You</title> 
    </head> 
    <body> 
    <hl>Thank you for filling out our survey.</hl> 
    <h3>The following is a copy of the information that we received.</h3> 
    <table border="0"> <tr> 
    <td>Name:</td> 
    <tdx#Namex/td> </tr> <tr> 
    <td>Address:</td> 
    <tdx#Addressx/td> </tr> <tr> 
    <td>Phone:</td> 
    <tdx#Phonex/td> </tr> <tr> 
    <td>E-mail:</td> 
    <tdx#emailx/td> </tr> </table> 
    <h5>We will be  contacting you shortly.</h5> 
    </body> 
    </html> 

    Главное, на что следует обратить внимание в этом файле, — это объекты 
ТТад, представленные в виде дескрипторов <#NAME> или <#EMAIL>. В процессе 
обработки файла TPageProducer, встречаясь с такими дескрипторами, будет 
вызывать обработчик события OnHTMLTag для каждого из них, и в этом обработчике 
можно определить, какой именно объект ТТад обрабатывается и чем он должен быть 
заменен в результирующей странице. 
    Чтобы создать подобную Web-страницу, выполните следующие действия. 
    1.	Поместите копию HTML-шаблона на сервер и запомните полный путь к ней. 
    2.	Если проект WebDemo не загружен в среду Delphi, загрузите его. 
    3.	Поместите в модуль компонент TPageProducer со страницы Internet. 
    4.   Укажите в качестве значения свойства HTMLFile путь к вашему шаблону. 
Заметим, что часто удобнее указать относительный путь, чем полный. 
    5.   Выберите вкладку Events в инспекторе объектов и дважды щелкните на 
строке события OnHTMLTag для добавления текста обработчика (рис. 28.7). 

    670 Часть VI. Сложный материал 


    ПРЕДОСТЕРЕЖЕНИЕ 

    Убедитесь, что введен корректный путь к шаблону. Это должен быть путь к 
шаблону на сервере, а не к шаблону на локальном компьютере разработчика (если 
это два разных компьютера). 

    Рис. 28.7. Проект WebDemo с компонентом TPageProducer 

    Приведенный ниже маленький текст процедуры делает большое дело. 

    procedure TWebModulel.PageProducerlHTMLTag(Sender:   TObject; 
    Tag:   TTag;   const   TagString:   String; TagParams:   TStrings; var 
ReplaceText:   String); var  Data:   TStrings; begin 
    Data   :=  nil; with Request  do begin case MethodType  of 
    mtPost:   Data   := ContentFields; mtGet   :   Data   :=  QueryFields; end; 
    ReplaceText   :=  Data.Values(TagString); end; end; 

    Вам, возможно, не совсем понятно, как получен доступ к введенной 
пользователем информации. Дело в том, что хотя объект Request и не передан в 
качестве параметра, он остается доступным. После получения доступа к свойствам 
объекта Request вы должны проверить его свойство MethodType, так как от типа 
передачи информации зависит^емоких переменных она будет храниться. Если 
значение свойства MethodType равно mtGet, информацию следует брать из 
по-ля~ОиегуР1еТсПз7а"если mtPost, то из поля ContentFieltis, 
    Далее определим, какой именно объект TTag вызвал процедуру, и заменим его 
соответствующим значением из введенных параметров. Для этого используется 
метод Values. Этот метод по известной левой части пары имя=значение вы

    Глава 28. Создание приложений для Web-cepeepa 671 

    дает значение правой части. Это легко осуществляется, так как 
использовались QueryFields и ContentFields, которые содержат разобранную информацию. 
    Все, что осталось сделать, — корректно настроить компонент Actionltem для 
выполнения действий по выводу страницы. Выполните следующие действия. 
    1.   Добавьте в проект новый компонент Actionltem. 
    2.   Присвойте ему имя aiParseFile и установите для его свойства Pathlnf о 
значение /ParseFile. 
    3.   Для обработчика события OnAction используйте код Response. Content   
:= PageProducerl. Content;. 
    4.   Скомпилируйте проект и поместите DLL в соответствующий каталог сервера. 
    5.   Поместите документ FormOl .htm на WWW-сервер и убедитесь, что 
дескриптор action указывает на файл Web-Demo, dll. 
    6.   Поместите шаблон ThankYou.htm в каталог, указанный в свойстве 
PageProducerl .HTMLFile. 
    7.   Откройте форму FormOl. htm в броузере (рис. 28.8). 

    Рис. 28.8. Форма, результаты ввода в которую представлены на рис. 28.9 и 28.10. 

    8.   Заполните форму и щелкните на кнопке подтверждения. 
    Проверьте URI в вашем броузере, обратив внимание на параметры, которые 
должны соответствовать введенной вами информации. 
    Вернитесь к форме. 
    9.   Заполните нижнюю форму и посмотрите на URI. Обратите внимание, что в 
этом случае введенная информация в URI не передается, что может быть весьма 
полезно, например, при вводе паролей.	"" 

    672 Часть VI. Сложный материал 


    Рис. 28.9. Результат работы метода GET 

    Рис. 28.10. Результат работы метода POST 


    Глава 28. Создание приложений для Web-cepeepa 
    673 22 Использование Delphi 3. Специальное издание 


    Добавление связи с базами данных 

    Итак, вы умеете выводить статические HTML-страницы и страницы, содержимое 
которых зависит от ввода пользователя. В этом разделе вы используете 
существующую базу данных для представления информации пользователю. Чтобы 
сделать это, вам необходимо немного больше знаний об Internet-компонентах 
Delphi 3. 
    Компонент TDataSetTableProducer предназначен для организации вывода 
стандартной HTML-таблицы на основе стандартного объекта базы данных. Таким 
объектом могут быть компоненты TTable, TQuery или один из новых наборов 
данных, доступных в Delphi 3. 
    Компонент TQueryTableProducer отличается от компонента 
TDataSetTableProducer тем, что работает с запросами, параметры которых заданы 
в форме SQL. 
    Как обычно, лучший способ изучения — практическая работа. Поэтому 
продолжим наращивать возможности нашей библиотеки WebDemo. dll. 
    1.	Загрузите проект WebDemo в интегрированную среду Delphi 3. 
    2.	На странице палитры компонентов Data Access выберите компонент TSession 
и поместите его в модуль. 
    3.	Установите значение свойства AutoSessionName компонента TSession равным True. 
    4.	На странице Internet выберите компонент TDataSetTableProducer и 
поместите его в модуль. 
    5.	Поместите в модуль компонент TTable со страницы Data Access. 
    6.	Присвойте свойству Tablel. Database значение DBDEMOS. 
    7.	Установите для свойства Tablel .TableName значение CUSTOMER.DB. 
    8.	Установите для свойства TDataSetTableProducer I. DataSet значение Tablel. 
    9.	Для свойства TDataSetTableProducerl .MaxRows установите значение 200. 
    Добавьте компонент TSession для отработки нескольких одновременных 
обращений к базе данных. Не забудьте, что мы создаем DLL и одновременно может 
быть запущено несколько процессов с ее участием. 
    Компонент TTable определяет интересующий нас набор данных, a 
TDataSetTableProducer необходим для получения HTML-таблицы. Свойство MaxRows 
устанавливает количество строк данных (не более 200). Поскольку 
TDataSetTableProducer возвращает всю таблицу, в нее следует включить только 
необходимые поля. 
    1.	Щелкните правой кнопкой мыши на компоненте TTable и выберите команду 
Fields Editor. 
    2.	Щелкните правой кнопкой мыши в окне редактора полей и выберите команду 
Add Fields. 
    3.	Выберите поля CustNo, Company, City, State и Phone. 
    Итак, вы заложили фундамент HTML-таблицы, которую правильно воспримет и 
красиво покажет WWW-броузер. Но — увы! — вы получаете только голые данные, и — 
ура! — у вас есть возможность добавить текст с помощью свойств Header и Footer 
объекта TDataSetTableProducer. Оба эти свойства — объекты TStrings. 
    Присвойте следующий HTML-текст свойствам Header и Footer. 

    DataSetTableProducer 1.Header := 
    <html> 
    <head> 
    <title>For Internal Use Only</title> 
    </head> 
    <!— Note: You will need to change the image source to reflect the true 
location of the image on your system —> 
    <body> 
    <center> 
    <hlxfont  color="#FFOOOO">For  Internal  Use  Only</fontx/hl> 
    <pximg  src="http://localhost/Warning.gif"  width="28"  height="28"x/p> 
    </center> 
    <!--  Header.htm ends  here  --> DataSetTableProducer 1 .Footer := 


    674     Часть VI. Сложный материал 


    <!-- Footer.htm begins here --> 
    <hr> 
    <p>Send any corrections  to 
    <a  href="mailto:jsmith@company.com">John  Smith</a> 
    </body> </html> 
    Свойства установлены. Теперь следует дописать код. 
    1.   Добавьте еще один компонент Actionltem в модуль DLL. Установите для 
его свойства Name значение aiDataSet. a для свойства Pathlnf о — /SfiowTabTe!~~~ 
    2.   Добавьте приведенный ниже код в обработчик события OnAction. 

    procedure TWebModulel.WebModulelActions3Action(Sender:   TObject; 
    Request:   TWebRequest;   Response:   TWebResponce; 
    var Handled:   Boolean); begin 
    with  DataSetTableProducerl  do begin 
    //Создать   заголовок. 
    Caption   :=   '<Hl>Phone   List</Hl>'; 
    //Устанавливаем свойства  выравнивания  заголовка. 
    CaptionAlignment   :=  саТор; 
    //Открываем данные. 
    DataSet.Open; 
    //Создаем таблицу для  вывода. 
    Response.Content   :=  DataSetTableProducerl.Content; 
    //Закрыть   данные. 
    DataSet.Close; end; end; 

    3.   Поместите рисунок (warning, gif) на сервер и измените соответствующим 
образом текст свойства Header, чтобы он указывал верное местоположение файла. 
    4.   Скомпилируйте DLL (рис. 28.11), перенесите ее на сервер и протестируйте. 

    Преимущества дополнительных возможностей компонента TQueryTableProducer 

    Компонент TQueryTableProducer разбирает входные параметры и вставляет их в 
соответствующие поля SQL-выражений с внедренными значениями TParams. Вы должны 
только установить стандартный объект TQuery в свою DLL, а остальное компонент 
TQueryTableProducer сделает вместо вас (рис. 28.12). Вот как этого достичь. 
    1.	Перетащите в окно WebModule стандартный компонент TQuery со страницы 
Data Access. 
    2.	Установите для свойства DatabaseName значение DBDEMOS. 
    3.	Для свойства SQL определите следующий текст. 
    SELECT  MASTER."SYMBOL"   AS   Symbol,   MASTER,"RCMNDATION"  AS   
Recommend, <b      INDUSTRY."IND_NAME"   AS   Industry 
    FROM   "MASTER.DBF"   MASTER,    "INDUSTRY.DBF"   INDUSTRY WHERE    
(MASTER.INDUSTRY=INDUSTRY.IND_CODE)   AND ((MASTER."RISK"   =:   Risk)   AND   
(MASTER."RATING"   =:   Rate)} ORDER  BY   INDUSTRY."IND_NAME" 
    4.	Приведите параметры Rate и Risk к типу данных strings. 
    5.	Поместите в окно WebModule со страницы Internet компонент TQueryTableProducer. 
    6.	Установите для его свойства Query значение Queryl. 
    7.   Установите для свойства RowAttributes .Align значение haCenter, чтобы 
выровнять данные в ячейках таблицы по центру. 
    8.   Установите для свойства TableAttributes . Border значение 1, чтобы 
заключить таблицу в рамку. 

    Глава 28. Создание приложений для Web-сервера	675 


    Рис. 28.11. Добавление компонентов связи с базами данных в проект 

    Рис. 28.12. Таблица в броузере 


    676 Часть VI. Сложный материал 

    Теперь, после установки свойств компонента TQuery, параметры для обработки 
запроса вставятся в соответствующие поля SQL-запроса и компонент 
TQueryTableProducer (рис. 28.13) обработает запрос, как обычный запрос 
приложения для работы с базами данных. 
    Следующий шаг— добавление в проект еще одного компонента Actionltem с 
именем aiQueryTable и свойством Pathlnf о —/Query. 

    Рис. 28.13. Проект WebDemo с компонентом TQueryTableProducer 

    Так же, как и TDataSetTableProducer, компонент TQueryTableProducer имеет 
свойства Header и Footer. Для установки этих свойств воспользуемся приведенным 
ниже кодом. 

    procedure  TWebModulel.WebModuleActions4Action(Sender:   TObject; Request: 
  TWebRequest;   Response:   TWebResponce; var Handled:   Boolean); begin 
    with  QueryTableProducerl   do  begin 
    Caption   :=   'Stock  Recommendations'; 
    Header.Add('<HTML>'); 
    Heade r.Add('<BODY>'); 
    Footer.Add('</BODY>'); 
    Footer.Add('</HTML>'); 
    //Устанавливаем связь. 
    Query   :=  Queryl; 
    //Открываем запрос. 
    Query.Open; 
    //Возвращаем результат. 
    Response.Content := QueryTableProducerl.Content; 
    //Закрываем запрос. 
    Query.Close; end; end; 


    Глава 28. Создание приложений для Web-сервера 677 

    Можно украсить таблицу, выводя фон ячеек разными цветами, однако не все 
броузеры способны поддерживать такую раскраску (Internet Explorer 3.x ее 
поддерживает). Ниже приведен пример использования предоставляемых возможностей 
при обработке события OnFormatCell. 

    procedure  TWebModulel.QueryTableProducerlFormatCell ( 
    Sender:   TObject; CellRow,   CellColumn:   Integer; var  BgColor:   
THTMLBgColor; var  Align:   THTMLAlign; var  VAlign:   THTMLVAlign; var 
CustomAttrs,   CellData:   String); 
    begin 
    if		CellData =	'BUY'	then	BgColor	:= 'Green' 
    else	if	CellData =	'SELL'	then	BgColor	:= 'Red' 
    else	if	CellData =	'HOLD'	then	BgColor	:= 'White' 
    end; 

    Можете изменить не только цвет фона, но и, например, выравнивание в ячейке. 
    Скомпилируйте весь проект и используйте для его тестирования листинг 28.3. 
Результаты тестирования должны выглядеть приблизительно так, как на рис. 28.14 
и 28.15. Приведенный листинг находится на дополнительно распространяемой дискете. 

    ЦЛистинг 28.3. /UDELPHI3/CHP28/FORM02. нтм. Форма для тестирования 
компонента aiQueryTable 

    <html> 
    <head> 
    <title>Web Server Applications</title> 
    </head> 
    <body bgcolor="#FFFFFF"> 
    <hl align="center">Web Server Applications</hl> 
    <h2>Show Table From Query</h2> 
    <p>This example shows how an ISAPI DLL is used to return a standard HTML 
page containing a table based on a Query.</p> <form 
action="../scripts/WebDemo.dll/Query" method="POST"> 
    <p>Rate: <'s"e^TeTt~"n^fe'e="1rRate'r''™srze=wT'1*5'' \     
<option>A</option> I     <option>B</option> |     <option>C</option> ! </selectx/p> 
    '*' <p>Risk: <select name="Risk" size="l"> <option>LOW</option> 
<option>MED</option> <option>HIGH</option> </selectx/p> 
    <pxinput type="submit"xinput type="reset"x/p> </form> 
    </body> </html> 


    678	Часть VI. Сложный материал 


    Рис. 28.14. Форма Form02. htm с выбранными значениями полей 

    Рис. 28.15. Результат выполнения запроса, показанного на рис. 28.14 


    Глава 28. Создание приложений для Web-cepeepa 679 


    Резюме 

    Итак, вы создали свою первую ISAPI-DLL в Delphi 3 и можете сами оценить, 
насколько это сложно. Основное, что следовало понять в этой главе, — как 
получить ввод пользователя и вернуть HTML-страницу броузеру. 
    Следует четко представлять, что вы не ограничены показом каких-либо таблиц 
или выводом текущего времени — вы вольны делать в своем приложении все что угодно. 
    Вероятно, вы уже начинаете раздумывать о том, как улучшить и приукрасить 
свой Web-сервер. Вспомните, что, помимо Delphi 3, есть еще много 
специализированных языков программирования и сценариев, а потому не 
замыкайтесь только на Delphi. 

    680 Часть VI. Сложный материал 
