ДонНУ, кафедра КТ, проф. В. К. Толстых Технологии разработки Internet- приложений Среда Delphi: CGI, ISAPI приложения Потоки, почта, куки, авторизация, Потоки, почта, куки, авторизация, IntraWeb Из цикла лекций «Технологии разработки Internet-приложений» для студентов 4-го курса кафедры Компьютерных технологий физического факультета Донецкого национального университета
Потоки С помощью потоков можно передавать данные практически любого типа (MIME – Multipurpose Internet Mail Extension), из любого источника, доступного на Web-сервере. При получении информации конкретного типа браузер отыскивает приложение, которое должно использоваться для обработки данных этого типа, после чего передает ему эти данные Основные свойства: Response.ContentStream – содержимое потока Response.ContentType – MIME-тип пересылаемых данных Основной метод: Response.SendResponse – отправить ответ Типы потоков в Delphi: TFileStream, TStringStream, TMemoryStream (буфер в ОЗУ), TBlobStream (чтение/запись полей Binary large object), TWinSocketStream (чтение/запись в сокете), TOleStream (COM интерфейс чтения/записи)
Пример 1 Передача изображения потоком TFileStream (из файла)
Запрос клиента Разные потоки Доставить мышонка!
Ответ сервера Обработчик события onAction 1 (без PathInfo) procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var Page: TStrings; begin Page:=TStringList.Create; With Page do begin Add(' '); Add(' Вот он! '); Add(''); Add(' '); end; Response.Content:= Page.Text; Page.Free; end; Вызов второго Action с PathInfo - mouse
Ответ сервера Обработчик события onAction 2 (PathInfo - mouse) procedure TWebModule1.WebModule1WebActionItem2Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var FS: TFileStream; begin // Создаём поток из файла mouse.gif: FS:=TFileStream.Create('../Images/mouse.gif',fmOpenRead); Response.ContentType:='image/gif'; //необходим модуль GIFImage Response.ContentStream:=FS; Response.SendResponse; // можно не удалять объект-поток, он будет удален автоматически // при завершении обработчика onAction end;
Пример 2 Передача изображения потоком TMemoryStream Var Jpg: TJPEGImage; B: TBitmap; MS: TMemoryStream; begin Jpg := TJPEGImage.Create; //пусть поток будет - jpeg try B := TBitmap.Create; //пусть исходный рисунок будет - bmp try ProcGenerate(B); //создание рисунка bmp … Jpg.Assign(B); //конвертирование bmp в jpeg finally B.Free end; MS := TMemoryStream.Create; Jpg.SaveToStream(MS); //запись в поток данных объекта Jpg MS.Position := 0; //текущую позицию потока – в начало Response.ContentType := 'image/jpeg'; Response.ContentStream := MS; finally Jpg.Free; {поток удалять не надо} end; end;
Создание рисунка для потока procedure ProcGenerate(var B:TBitmap); begin With B Do begin Width := 300; Height := 300; Canvas.TextOut(0,0,'Создал Красников'); Canvas.Pen.Color := clTeal; Canvas.Pen.Width := 2; r:=0; while r
Результаты работы
Почта - Indy Internet Direct – открытые Internet-компоненты Основные свойства TIdSMTP – реализует клиентский SMTP-протокол Host :String – адрес (IP, доменный) удаленного SMTP-сервера PORT:Integer – для SMTP=25 UserName :String – login автора сообщения Password :String – пароль автора сообщения (для аутентификации) AuthenticationType – (atNone, atLogin) без или с простой проверкой подлинности AuthSchemesSupported :TStringList методы аутентификации SMTP-сервера Основные свойства TIdMessage : содержит Internet-сообщение From.Text :String – адрес отправителя Recipients. Addresses :String – адреса получателей, через запятую ContentType :String – MIME-тип сообщения CharSet :String – кодировка шрифта, например CharSet:='windows-1251' ; Body: TStrings – тело сообщения Subject :String – тема сообщения
Компоненты From, Recipients и их свойства Свойства TIdMessage.From : автор сообщения (стандарт RFC 822) Address, Name, Text : String – адрес отправителя Пример, IdMessage.From.Name := 'Jane Doe'; IdMessage.From.Address := IdMessage.From.Text := '"John Doe" '; // IdMessage.From.Text содержит 'Jane Doe ' // IdMessage.From.Name содержит 'John Doe' // IdMessage.From.Address содержит Свойства TIdMessage.Recipients : получатель Addresses: String – адрес отправителя (стандарт RFC 822) Items[0-2] – поля Address, Name,Text как в адресе отправителя
Отправка сообщений Пример отправки сообщения IdMessage1 с возможной аутентификацией: With IdSMTP1 Do begin AuthenticationType:=atNone; try Connect; if AuthSchemesSupported.IndexOf('LOGIN')>-1 then // требуется ли аутент.? begin AuthenticationType:=atLogin; Authenticate; end; // - если «да» Send(IdMessage1); Disconnect; finally IdMessage1.Destroy; end; // - если оно дальше не нужно end; Основные методы TIdSMTP : Create, Destroy – создание, удаление объекта типа TIdMessage ClearHeader, ClearBody, Clear – очистить заголовок, тело, всё Connect – установить связь с SMTP-сервером для отправки сообщения Send(сообщение типа TIdMessage) – отправить сообщение Disconnect – разорвать связь с SMTP-сервером Authenticate: Boolean – выполнить аутентификацию, при успехе - True
Пример создания сообщения Var IdMessage1: TIdMessage; … begin // данные для подключения к SMTP (настройка IdSMTP1) IdSMTP1.Host:=' '; IdSMTP1.UserName:='Vova'; IdSMTP1.Password:='xxxxxxxx'; IdMessage1:= TIdMessage.Create(nil); // создание письма With IdMessage1 Do begin // создание заголовка и тела письма ContentType:='text/plain'; CharSet:='windows-1251'; Subject:='тема письма'; Body.Add('строка 1'); Body.Add('строка 2');… End;
Cookie Постоянным файлом Cookie называется файл, сохраняемый на компьютере после выхода из браузера. Этот файл Cookie может быть прочитан сайтом при его повторном посещении. Сохраненный на компьютере файл Cookie может прочитать только тот сайт, который его создал. Браузер, перед соединением с каждым сайтом, проверяет нет ли от него Cookie, если есть – добавляет его содержимое к HTTP- запросу этого сайта. Временные (сеансовые) файлы Cookie сохраняются только в течение текущего сеанса обозревателя и удаляются с компьютера после выхода из браузера. Cookie (печенье, проныра) - это текстовая строка, которая может включаться в запросы и ответы протокола HTTP. Разработчики Web- приложений организуют хранение в файлах Сookie на компьютере пользователя такие сведения, как персональные данные пользователя, логин и пароль, свои глобальные переменные и др. данные необходимые им для обработки последующих посещений клиента. Файл Cookie – до 4 Кб, - до 300 файлов для каждого пользователя, до 20 значений от одного домена
Заголовок Cookie 1 Заголовок Cookie 2 Cookie «Коллекции» PREF ID=87b064fd051aeab5:TM= :LM= :S=BBYhpV8Zu96 Jn_bq google.com/ * Cookie 1 Cookie 2 - имя Cookie 1 - его значение - имя Cookie 2 - его значение Cookie 1 Заголовок Cookie : LastVisit %3A38%3A38 localhost/net-web/Scripts/Cookie.exe/ * Hi Hallo%2C+Client! localhost/net-web/Scripts/Cookie.exe/ * Браузер отправляет серверу заголовки его коллекций cookie C:\Documents and Settings\пользователь\Cookies - имя Cookie - его значение При повторной записи Cookie значения одинаковых параметров обновляются, а новые – добавляются. При этом имя файла Cookie получает очередной номер в квадратных скобках.
Коллекция TCookieCollection для объекта Response - контейнер Response.Cookies объектов TCookie, - список всех заголовков Cookie в Web-ответе Основные свойства коллекции: Response.Cookies.Items[i]: TCookie – заголовок Cookie номер i в Web-ответе Response.Cookies.Count – количество Cookie в коллекции Основные методы коллекции: Response.Cookies.Add:TCookie – добавляет заголовок Cookie в Web-ответ свойства для TCookie : Name, Value, Domain, Path :String (ограничивает пути для Domain), Expires :TDateTime (срок жизни Cookie), Secure :Boolean (должен ли клиент использовать защищенное соединение https при передачи заголовка Cookie), HeaderValue (заголовок Cookie), Response.Cookies.Clear – удаляет все Cookie в коллекции Response.Cookies.Delete(i: Integer) – удаляет i-тый Cookie в коллекции
Метод Response.SetCookieField для добавления Cookie в Web-ответ SetCookieField (Values :TStrings (заголовки – имена и значения всех Cookie), Domain, Path, Expires, Secure) procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var List: TStrings; begin List:=TStringList.Create; // контейнер заголовков Cookie try List.Add('LastVisit='+ {имя Cookie 1} FormatDateTime('mm/dd/yyyy hh:mm:ss',Now) {значение Cookie 1}) ; List.Add('Hi='+ {имя Cookie 2 } 'Hallo, Client! {значение Cookie 2}) ; Response.SetCookieField(List,'','',Now+1,False); // срок жизни – 1 день Response.Content:=' Cookie Установлен! '; finally List.Free; end; end; Пример добавления Cookie:
Свойства Request для Cookie Методы Request для Cookie Основной метод Request: ExtractCookieFields (List: TStrings) – прочитать в контейнер List пары 'Name=Value ' всех Cookie List.Values['Name'] – прочитать значение 'Value' для Cookie с именем 'Name' из контейнера строк List Основные свойства Request: Cookie :String – заголовки всех Cookie, пришедших от клиента, т.е. пары Name=Value (другие не высылаются) через ; CookieFields :TStrings – контейнер строк-пар 'Name=Value'
Пример чтения Cookie procedure TWebModule1.WebModule1WebActionItem2Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); var List: TStrings; begin List:=TStringList.Create; // контейнер для всех заголовков Cookie try Request.ExtractCookieFields(List); {прочитать заголовки Cookie в список} Response.Content:=' '+ ' Значение Cookie 1: '+ List.Values['LastVisit']+ ' Значение Cookie 2: '+ List.Values['Hi']+ ' Свойство Request.Cookie: '+ Request.Cookie+' '; finally List.Free; end; end;
Демонстрация Cookie 1 2
Пример добавления Cookie через свойство Cookies (Авторизация) Здесь в Cookie записывается пароль авторизации, что позволяет клиенту не проводить авторизацию при посещении этого сайта в течение суток. Пароль из Cookie передается серверу при незащищенном (не https) подключении клиента и без встроенной проверки подлинности Windows. Код обработчика OnAction для работы с Cookie: Handled := False; // добавление Cookie не завершает Web-ответ with Response.Cookies.Add do begin Name := 'LastPassword'; // Установка Cookie LastPassword для текущей авторизации, // либо, если авторизация не была проведена, то чтение данных // об авторизации из cookie LastPassword запроса request: Value := Request.Authorization; if Value = '' then Value := Request.CookieFields.Values['LastPassword]; Secure := False; // требование незащищенного подключения Expires := Now + 1; // срок жизни – 1 день end; Далее, в других Action, можно проверить пароль в Value данного Cookie
Аутентификация и авторизация Установка доступа с проверкой подлинности встроенными средствами Windows Основана на обмене сервера зашифрованными сообще-ниями с Internet Explorer для подтверждения удостоверения пользователя
LastPassword web/scripts/Authorization.exe / * LastPassword Negotiate+TlRMTVNTUAADAAAAGAAYAHoAAAAYABgAkgAAABAAEABA AAAAGgAaAFAAAAAQABAAagAAAAAAAACqAAAABYKIoEQATwBOAE4 AVQBXAFcAVwBBAGQAbQBpAG4AaQBzAHQAcgBhAHQAbwByAFQATw BMAFMAVABZAEsASACPy1GbyQn5fQAAAAAAAAAAAAAAAAAAAABVD Kh%2FiIUNZrwwSNq4EULmSS069xQBU5c%3D * Cookie Результаты авторизации (переговоры) не анонимным доступом средствами Win – скрыты Результаты авторизации (переговоров) при анонимном доступе средствами Win можно сохранять в файл Идентификатор сессии Пароль
Очередной запрос при не сохранен- ном пароле Очередной запрос при сохраненном ранее пароле При обычной авторизации, не встроенными средствами Widows, пароль отправляется в текстовом формате и его можно сохранить и в системе и в файле Проверка подлинности «Обычная» - не встроенными средствами Windows
Создание IntraWeb приложения - технология создания Web-приложений от фирмы AtoZed IntraWeb – это разработка форм Web приложений, ничем не отличающаяся от разработки обычных форм. В результате получается приложение, генерирующее для клиента обычные HTML-страницы с кодом на JavaScript. Выдача результатов в HTML обеспечивает совместимость с самыми распространенными браузерами
IntraWeb
Код обработчика кнопки «Посчитать сумму» procedure TformMain.IWButton1Click(Sender: TObject); var a,b,res : Double; code : Integer; begin val(IWEdit1.Text,a,code); val(IWEdit2.Text,b,code); res:=a+b; IWEdit3.Text:=FormatFloat('0.##',res); end;
Запуск IntraWeb Запуск Результаты работы: