Из цикла лекций «Технологии разработки Internet-приложений» для студентов 4-го курса кафедры Компьютерных технологий физического факультета Донецкого национального университета Технологии разработки Internetприложений Среда Delphi: CGI, ISAPI приложения (В Visual Studio нет прямых и простых средств создания ISAPI расширений) Delphi –Windows, Kylex – Linux PageProducer ДонНУ, кафедра КТ, проф. В. К. Толстых Delphi – вид Web Server Application Создание Web-приложения Создание Web-модуля в приложении Если Action несколько, то для них надо указывать свои пути Сгенерированный код Web-модуля unit Unit1; interface uses SysUtils, Classes, HTTPApp; type TWebModule1 = class(TWebModule) procedure WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); private { Private declarations } Добавлен заголовок public обработчика onAction { Public declarations } end; var WebModule1: TWebModule1; (продолжение) Обработчик onAction 1 … implementation {$R *.dfm} Контейнер запроса Контейнер ответа procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); Begin Флаг для диспетчера о готовности ответа {место программирования кодов обработки Web-запроса} end; end. Рекомендации для создания и тестирования приложения • При тестировании Web-приложений в свойствах браузера в разделе «временные файлы» установить «Проверять наличие обновления… при каждом посещении страницы». • Создать Web-сайт, или Web-приложение (рекомендуем это!), или виртуальный каталог (см. Архитектура IIS.ppt), установить Web и NTFS разрешения (разрешить запуск сценариев и исполняемых файлов – для IIS5 и 6, для IIS7; запись в файлы – см. далее). • Для ISAPI (IIS 5) и ASP (IIS 6) отменить кэширование. • При работе в локальной сети можно использовать соседний IIS. Доступ к его корню – это http://имя компьютера, например, http://KT-61/ Убедитесь, что в настройках подключения браузера к сети его запросы не отправляются к удаленному прокси-серверу (отметить «не использовать проксисервер для локальных адресов») • Теперь можно в какой-либо среде разработки сайтов, например, SharePoint Designer 2007, Visual Studio… подключиться к созданному сайту (приложению, виртуальному каталогу) на локальном IIS и приступать к его разработке. Введите в строке открытия сайта – http://localhost/ваш_сайт Установка NTFS-разрешений 1. Убедитесь, что у вас есть закладка Безопасность в свойствах файлов и папок. Если нет, то в меню Windows Explorer выберете: Сервис – Свойства папки… – Вид – Использовать простой общий доступ к файлам – снять флаг, 2. Теперь для необходимого файла в его свойствах можно выбрать появившуюся закладку Безопасность, далее выберете имя пользователя от которого вы работаете, или – Гостевую учётную запись, и поставьте флаги на Чтение, Запись или Полный доступ для выбранного Вами ресурса. Web-модуль TWebModule = TDataModule + TWebDispatcher Основные свойства TWebModule: Actions => TWebActionItem: Default, Enabled, MethodType, PathInfo Событие: OnAction Web-диспетчер TwebDispatcher, согласно запросу, ищет действия с подходящими MethodType (POST, GET…) и PathInfo, если такое действие находится, то вызывается обработчик OnAction этого действия. Обработчик помещает ответ в WebResponse. Если формирование ответа не закончено, то устанавливают значение параметра Handled:=False (по умолчанию - True). В этом случае диспетчер запускает обработчик действия со свойством Default:=True, не зависимо от значений его свойств MethodType и PathInfo. Если значение PathInfo не определено и действие имеет значение Enabled=Default=True, то оно будет обработано первым. Если диспетчер не нашел ни одного действия, то связь сервера с клиентом разрывается без всяких сообщений. События: BeforDispatch, AfterDispatch Демонстрация передачи клиентом параметров методами GET, POST Форма запроса: Путь к Action GET (2 КБ) <form method="POST" action="http://localhost/Scripts/SendForm.dll/Main?MyGET1=g1&My%20GET2"> <input type="text" name="T1" size="20"> <input type="submit" value="Отправить" name="B1"> POST <input type="reset" value="Сброс" name="B2"> (8 МБ) <input type="hidden" name="hide" value="Скрытые данные"> </form> Пробел, преобразованный к 16-ричной форме TWebRequest Содержит информацию, присылаемую от Клиента в HTTP-запросе Основные свойства Request: RemoteHost, UserAgent, Accept, Referer, Authorization, Cookies…(см. далее) Content :String – строка запроса с разделителями = и & POST: ContentFields :TStrings – массив строк типа name=value ContentFields.Values['name элемента формы'] – чтение значения Value элемента формы по его идентификатору, определённому в атрибуте name Query :String – строка запроса с разделителями = и & GET: QueryFields :TStrings – массив строк, разделённых на символе & QueryFields.Values['имя параметра перед ='] – чтение значения параметра Параметры запросов GET, POST: Другие параметры запроса Web-Клиента Другие свойства Request через localhost Другие свойства Request через www.donnu.edu.ua TWebResponse Содержит информацию, отправляемую Клиенту на HTTP-запрос Основные свойства Response: Content – контейнер строк HTML-кода для ответа (отправки) клиенту Cookies, ContentType… Основные методы Response: SendResponse – отправить ответ (немедленно, не дожидаясь окончания OnAction) SendRedirect('новый URL') – перенаправить запрос Пример перенаправления запроса для дальнейшей обработки: 0 1 2 <A href=“http://www.donnu.ua?http://www.borland.com&Borland&DonNU”> Firm:=Request.QueryFields[1]; // статистика запросов для ДонНУ Response.SendRedirect(Request.QueryFields[0]+'? '+ // +GET-параметр Request.QueryFields[2]); // перенаправление TPageProducer Генератор HTML-страниц на основе шаблонов Основные свойства: HTMLFile, HTMLDoc – шаблон страницы Основной метод: Content – генерирует HTML-страницу (просматривает HTML-шаблон, генерирует событие onHTMLTag для каждого настраиваемого тега заменяет настраиваемый тег HTML-кодом) Событие: onHTMLTag – возникает при каждой встрече с настраиваемым тегом: <#имя_тега “парам=знач” “парам=знач”> Параметры процедуры (обработчика события) onHTMLTag: Tag type TTag = (tgLink, tgImage, tgTable, tgCustom …); <#Link…> <#Image…> <#Table…> <#любой…> TagString – только имя тега, TagParams – только параметры тега ReplaceText – заменяет настраиваемый тег HTML-кодом Работа с PageProducer подготовка запроса Клиентская часть <html> <body> <H2> Включение и удаление из списка рассылки </H2> Введите Ваше имя, адрес электронной почты, выберете нужный "Пункт“ <br> и нажмите кнопку "Включить" или "Удалить": <form method="POST" action="http://localhost/net-web/Scripts/PageProducer.exe"> <table border="0"> <tr><td width="15%">Имя: </td> <td width="85%"><input type="text" name="name"></td> </tr> <tr><td width="15%">E-mail: </td> <td width="85%"><input type="text" name="mail"></td> </tr> </table> <p> <input type="radio" name="R1" value="1" checked> Пункт 1 <br> <input type="radio" name="R1" value="2" > Пункт 2 </p> <p> <input type="Submit" name="B1" value="Включить"> <input type="Submit" name="B2" value="Удалить" > <input type="Reset" name="B3" value="Очистить ввод" ></p> </form> </body> </html> Ответ сервера Серверная часть Файл-шаблон ответа Код файла-шаблона ответа для PageProducer1.HTMLFile <HTML> <Body> <P><P><P> <H3><Font Color=Blue> Уважаемый коллега, <#Tag1>,<Br> <I> Спасибо за Ваш интерес к нашим разработкам! </Font></I></H3> <P> Ваша запись в списке рассылки: <P> <table border="1" width="85%"> <tr><td width="15%">E-mail: </td><td><#Tag2></td></tr> <tr><td width="15%">Пункт: </td><td><#Tag3></td></tr> </table> <#Blank> <P><HR> <Center><#Image></Center> </Body> </HTML> Подготовка ответа сервера Обработчик события onAction var Colleague, EMail,Item : String; Btn : Boolean; // - глобальные переменные procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); begin // определение имени коллеги Colleague:=Request.ContentFields.Values['name']; // определение e-mail EMail:=Request.ContentFields.Values['mail']; // обработка радиальных кнопок Case StrToInt(Request.ContentFields.Values['R1']) Of 1: Item:='Выбран Пункт 1'; 2: Item:='Выбран Пункт 2'; end; // "включить", "удалить" из списка If Request.ContentFields.Values['B1']='Включить' Then Btn:=True else Btn:=False; // формирование ответа Response.Content:=PageProducer1.Content; Handled:=True; // ответ готов end; Разборка настраиваемых тегов Обработчик события onHTMLTag (пример 1) procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String; TagParams: TStrings; var ReplaceText: String); begin Case Tag of tgCustom: If TagString='Tag1' Then ReplaceText:=Colleague else If TagString='Tag2' Then ReplaceText:=EMail else If TagString='Tag3' Then ReplaceText:=Item else If TagString='Blank' Then If Btn Then ReplaceText:=' ' else ReplaceText:='<Br><b><I>Указанная запись успешно удалена!</I></b>'; tgImage: ReplaceText:='<img src="../images/Back.gif" ' + 'alt="Вернуться назад" OnClick="window.history.back()" >'; end; end; Разборка настраиваемых тегов Обработчик события onHTMLTag (пример 2) procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String; TagParams: TStrings; var ReplaceText: String); begin If TagString='Tag1' Then ReplaceText:=Colleague; If TagString='Tag2' Then ReplaceText:=Email; If TagString='Tag3' Then ReplaceText:=Item; If TagString='Blank' Then If Btn Then ReplaceText:=' ' else ReplaceText:='<Br><b><I>Указанная запись успешно удалена!</I></b>'; If TagString='Image' Then ReplaceText:='<img src="../images/Back.gif" ' + 'alt="Вернуться назад" OnClick="window.history.back()" >'; end;