» ASP
для новичков
» Главная
страница
»
ASP
для новичков
Cookies
Cookies. Что же это такое, и
с чем их едят? Происхождение этого названия достаточно туманно, и по одной из
версий, оно пришло из неких мультсериалов, герои которых, съев волшебное
печенье, приобретали возможность обмениваться мыслями. Теперь эти cookie-файлы
поедают Web-серверы и системы удаленных пользователей. Правда, обмениваются они
не мыслями.
Cookies представляют собой
достаточно простой механизм обмена информацией между сервером и браузером. Во
время соединения сервер просто создает или открывает уже существующий файл в
системе удаленного пользователя, в котором сохраняет некую информацию, которая
потом будет применяться для идентификации пользователя и для оптимизации работы
с ним. Cookies— это своего рода памятные записки, как маленькие желтые листочки,
которыми мы обклеиваем свое рабочее место. Это как читательский билет, который
хранит информацию о наших вкусах и пристрастиях, показывает нашу "историю
взаимодействия" с данным конкретным сервером.
Еще одной проблемой,
связанной с данной технологией, является ее наименование в русском языке.
Несколько фривольные гастрономические переводы этого слова (пряники, печеньица),
естественно, не могут быть использованы в технической литературе, а прямая
калька с английского — куки — еще не прижилась, и звучит достаточно необычно,
несмотря на то, что именно этот вариант претендует на роль стандартного
обозначения в русском языке. Поэтому мы пока что будем обходиться англоязычным
наименованием — cookies. Но вернемся к технологическим проблемам.
Давайте посмотрим, как
происходит стандартная HTTP-транзакция. Сначала браузер обращается по URL и
входит в контакт с сервером. После этого, сервер пересылает браузеру некую
затребованную информацию, или сообщение об ошибке. Затем соединение разрывается,
и сервер более ничего не помнит о произошедшей транзакции. Таким образом,
последующие сеансы связи никак не скореллированы с результатами предыдущих
транзакций. Именно этот перекос в некоторой степени выправляют cookies.
Согласно стандарту, cookie
представляет собой обычную строку, не превосходящую по размеру 4000 символов,
которая отсылается сервером браузеру. Браузер анализирует полученный (ая/ое)
cookie, проверяет длину, дату истечения срока годности (best before ), после
чего сохраняет в отдельном файле. Важная деталь. Cookies не могут содержать
исполняемый или интерпретируемый код, а также его фрагменты.
Cookie содержит обязательные
поля, опциональные поля, а также любую другую информацию в текстовом формате,
обработку которой берет на себя сервер. Рассмотрим поля, которые могут
использоваться в cookies.
Стандартный вид заголовка
cookie выглядит следующим образом:
Set-Cookie:
пате=<значение>;
ехр!гез=<дата>;
path=<nyTb>;
domain= <имя домена>;
secure.
Разберем эти поля несколько
более подробно.
- nаmе=<значение>. Это
определение имени и содержания cookie. Как известно, один и тот же сайт, а в
нашем случае, одно и то же Web-приложение, может сохранять в локальной системе
удаленного пользователя несколько cookies. Естественно, их необходимо как-то
различать. Идентификация каждого cookie происходит именно по его наименованию.
Поэтому поле name является обязательным.
- ехрirеs=<дата>. Это
срок годности cookie, а точнее момент истечения срока его годности по
гринвичскому меридианному времени. Например, Monday, 9-August-1999 22:00:00 GMT.
- path=<nyTb>. В случае
задания этого параметра, cookie будет возвращен браузером серверу только в том
случае, если будет запрошен URL с этого пути. Например, если задано
path=<books>, то cookie будет выдан только при затребовании документов,
лежащих в этом каталоге, или в его подкаталогах. Если этот параметр не будет
указан, то он будет устанавливаться автоматически, причем, в качестве пути будет
взят путь первого запрошенного URL. При помощи этого параметра мы можем
создавать отдельные cookies для каждой Web-страницы, входящей в состав нашего
сайта.
- domain=<MMH доменах В
этом параметре определяется имя домена, куда будут возвращаться cookies. Для
доменов com, edu, net, org, gov, mil, int, biz и info необходимо задавать как
минимум два периода имени сервера. Например, amazon.com будет означать любые
имена вида *.amazon.com. Для других доменов — не менее трех периодов. По
умолчанию это имя домена есть имя сервера, приславшего cookie.
- secure. Если в нашем cookie
есть это поле, то он будет возвращаться только на сервер, обеспечивающий
сертифицированный метод безопасности, обычно SSL (Secure Socket Level).
Теперь, когда мы знаем, как
выглядят cookies, и для чего они нужны, рассмотрим методы работы с ними,
применяемые в ASP.NET. Следует отметить, ЧТО СВОЙСТВО Cookies ВХОДИТ В состав
объектов HttpResponse и HttpRequest. Это свойство имеет тип HttpCookieCoiiection
и является, как несложно понять, коллекцией. Состоит эта коллекция из элементов
типа HttpCookie, и перед тем, как рассматривать детально коллекцию, узнаем, как
устроены ее элементы. Уникальных методов у данного типа нет, и это понятно.
Любой cookie это всего лишь набор данных, и тип HttpCookie предназначен главным
образом для получения данных из cookie без синтаксического разбора его строки. В
свойствах типа HttpCookie содержатся значения всех полей cookie как стандартных,
так и введенных разработчиком. -Рассмотрим эти свойства.
- Domain. Свойство содержит
значение типа string, в котором записывается доменное имя сайта, с которого
устанавливается данный cookie.
- Expires. Свойство содержит
значение типа DateTime, которое устанавливает срок действия cookie.
- HasKeys. Свойство
логического типа Boolean. В том случае, если cookie помимо стандартных полей
содержит дополнительную информацию, используется значение True. Значение этого
свойства нельзя устанавливать программно, оно доступно лишь для чтения.
- Name. Свойство типа string.
Его значением является наименование cookie.
- Path. Свойство содержит
значение типа string, в котором указывается путь к некоему виртуальному
каталогу. Как мы уже знаем, если явно установлено значение данного свойства,
cookie будет выдаваться системой удаленного пользователя только тем
Web-страницам, которые располагаются в указанном каталоге или в его
подкаталогах. Можно сказать, что это свойство несколько уточняет область
действия свойства Domain.
- Secure. Свойство
логического типа Boolean. Значение True указывает, что cookie отправляется на
систему удаленного пользователя или получается из нее только по защищенному
протоколу, такому, как, например, HTTPS. По умолчанию используется значение
False.
- Value. Значение типа string
является содержимым самого cookie. Данное свойство доступно только для чтения.
- Values. Свойство является
коллекцией типа NamevaiueColiection и содержит значения всех параметров искомого
cookie. Естественно, если мы используем данное свойство, мы предполагаем, что в
одном cookie использовано несколько параметров, и тогда свойство HasKeys должно
иметь значение True. Как и предыдущее свойство, эта коллекция может лишь
предоставлять приложению данные, но программно их изменить нельзя.
Теперь, когда мы знаем, как
именно устроены элементы коллекции HttpCookieCollection, мы можем перейти к
рассмотрению ее структуры.
Свойства у типа этой
коллекции вполне стандартны и присущи в равной мере всем типам-коллекциям, а
набор методов несколько специфичен. Именно при помощи этих методов приложение
получает возможность оперировать с cookies, содержимое которых задано при помощи
типа HttpCookie.
- Add. Метод добавляет в
коллекцию еще один cookie. В качестве параметра передается значение типа
HttpCookie. Естественно, желательно задать содержимое этого cookie заранее, до
выполнения метода Add.
- clear. Метод очищает
содержимое всей коллекции. При помощи этого метода мы можем уничтожить все
cookies, входящие в искомую коллекцию.
- соруто. Метод позволяет
копировать в некий массив содержание всех cookies, входящих в коллекцию.
Содержимое cookies, естественно, копируется в массив в виде строк, т. е.
используется тип string. В качестве параметров методу передается сам массив, в
который будет происходить копирование, и целое число, являющееся номером
элемента массива, с которого начнется копирование информации.
- GetKey. Метод возвращает
наименование cookies, входящего в коллекцию, в виде строкового значения типа
string. В качестве значения методу передается целое число, которое является
порядковым номером cookies в коллекции. Естественно, метод вернет наименование
именно того cookies, чей порядковый номер был передан в качестве параметра.
- Remove. Метод позволяет
удалить из коллекции тот или иной cookie. В качестве параметра методу передается
наименование того cookie, который подлежит удалению из коллекции. Естественно,
передаваемый параметр имеет тип string.
- Set. Метод позволяет
изменить содержимое какого-либо cookie. В качестве параметра методу передается
значение типа HttpCookie, в котором уже были произведены необходимые изменения.
Теперь, когда мы знаем,
какие средства работы с cookies есть в нашем распоряжении, рассмотрим примеры
использования этих механизмов. Начнем мы с установки cookies в систему
удаленного пользователя. При входе на сайт предложим ему указать свое имя. Для
того чтобы в дальнейшем сайт мог "узнать" и поприветствовать этого пользователя
при его новых заходах, мы можем сохранить в cookies имя, указанное
пользователем, и дату его последнего визита на сайт. Естественно, для того чтобы
записать информацию в локальную систему пользователя, нам придется
воспользоваться объектом HttpResponse и его свойством Cookies. Естественно, в
состав объекта HttpResponse не входит какой-либо метод, который явно записывает
cookies в системе удаленного пользователя. Нам достаточно всего лишь создать
элементы коллекции Cookies, а они будут переданы браузеру пользователя без
каких-либо дополнительных директив, так как объект HttpResponse как раз и создан
для передачи информации удаленному пользователю. Стоит также отметить, что все
cookies будут передаваться браузеру при помощи заголовков HTTP с наименованием
set-cookie.
Но перейдем все-таки к
рассмотрению листингов. Как всегда, попробуем создать код, опираясь на наши
предыдущие наработки. Предположим, что у нас есть маленькая форма, в которой мы
запрашиваем у пользователя его имя. Нам потребуются одно поле текстового ввода и
кнопка подтверждения. В листинге 3.30 приведен HTML-код этой Web-страницы в том
виде, как он показан в среде разработки Visual Studio .NET.
Л
истинг 3.30
<%@ Page Language="vb"
AutoEventWireup="false"
Codebehind="WebForml.aspx.
vb" Inherit s= "cookies. WebForml"%>
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD
HTML 4.0
Transitional//EN">
<HTML>
<HEAD>
<titlex/title>
<meta name="GENERATOR"
content="Microsoft Visual Studio. NET 7.0">
<meta
name="CODE_LANGUAGE" content="Visual Basic 7.0">
<meta
name="vs_defaultClientScript" content="JavaScript">
<meta
name="vs_targetSchema" con-tent="http: //schemas .microsoft .
com/intellisense/ie5">
</HEAD>
<body
MS_POSITIONING="GridLayout">
<form id="Forml"
method="post" runat="server">
<asp:Label id="Labell"
style="Z-INDEX: 101; LEFT: 40px;
POSITION: absolute;
TOP: 26px"
runat="server">yKa;KMTe Ваше HMH</asp:Label>
<asp:TextBox
id="TextBoxl" style="Z-INDEX: 102; LEFT: 43px;
POSITION: absolute;
TOP: 51px" runat="server"
Width="222px" Height="24px"x/asp:TextBox>
<asp:Button id="Buttonl"
style="Z-INDEX: 103; LEFT: 50px;
POSITION: absolute; TOP:
88px" runat=" server" Text="noflTBeproiTb"></asp:Button>
</form>
</body>
</HTML>
Естественно, основная работа
будет производиться сервером при нажатии пользователем на кнопку. Но для того
чтобы увидеть, какие именно действия будет производить приложение, необходимо
рассмотреть код класса, реализующего данную Web-страницу. Он приведен в листинге
3.31.
Листинг 3.31
Public Class WebForml
Inherits System. Web. UI .
Page
Protected WithEvents Labell
As System. Web. UI .WebControls . Label Protected WithEvents TextBoxl
As System. Web. UI.
WebControls .TextBox Protected WithEvents Buttonl
As System. Web. UI
.WebControls .Button
iRegion " Web Form Designer
Generated Code "
'This call is required by
the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough(}> Private Sub
InitializeCcnponent()
End Sub
Private Sub Page_Init(ByVal
sender As System.Object, ByVal
e As System.EventArgs)
Handles MyBase.Init
'CODEGEN: This method call
is required by the Web Form Designer
'Do not modify it using the
code editor. InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal
sender
As System.Object, ByVal
e As System.EventArgs)
Handles MyBase.Load
'Put user code to initialize
the page here
End Sub
Private Sub
Buttonl_Click(ByVal sender
As System.Object, ByVal e As
System.EventArgs) Handles Buttonl.Click
Dim MyCookie As New
HttpCookie("Cookiel") Session.Add("NAME", TextBoxl.Text) MyCookie.
Value = TextBoxl.Text
MyCookie.Values("Time") =
DateTime.Now().ToString() Response.
Cookies.Add(MyCookie)
Response.Redirect("WebForm2.aspx")
End Sub
End Class
Рассмотрим тщательно всю
последовательность операций, которые выполняются в обработчике нажатия на
кнопку. Прежде всего, мы объявляем переменную MyCookie типа HttpCookie, которая
обладает наименованием Cookiel. После объявления этой переменной мы добавляем в
коллекцию объекта session элемент с наименованием name, в который мы заложим
текст, введенный пользователем в текстовое поле. Потом этот элемент будет
воспринят второй Web-страницей и обработан ею. Механизм работы второй
Web-страницы для нас сейчас абсолютно неинтересен, поэтому сосредоточимся на
рассмотрении листинга 3.31. В самом начале работы процедуры мы создали
переменную типа HttpCookie. Основное значение данного cookie будет содержать имя
пользователя, которое тот указал в поле текстового ввода. Для занесения этого
имени в переменную мы используем свойство Value.
Но было бы неплохо еще
запомнить дату и время его последнего посещения нашего сайта. Поэтому при помощи
коллекции values мы создаем в cookie еще одно поле с наименованием Time, в
которое мы записываем текущее время. После того, как cookie полностью создан, мы
добавляем его в коллекцию при помощи оператора Response.
Cookies. Add (MyCookie). И по -следним действием процедуры
мы переадресуем пользователя на другую Web-страницу, с наименованием
WebForm2.aspx. Именно в этот момент, вместе с содержимым этой Web-страницы
браузер пользователя получает инструкцию, записать в локальную систему
содержимое cookie.
Но записать cookie — это
только половина дела. Необходимо еще получить их при последующем посещении сайта
тем же пользователем и правильно его обработать. В рамках уже существующего
проекта можно создать третью Web-страницу, которая при обращении пользователя к
ней будет получать cookie и обрабатывать его.
На этой странице мы можем
расположить всего один компонент Label и формировать его текстовое содержимое
динамически, опираясь на информацию, заложенную в cookie. Класс, реализующий эту
страницу, приведен в листинге 3.32.
Листинг 3.32
Public Class WebFormS
Inherits System.Web.UI.Page
Protected WithEvents Labell
As
System.Web.Ul.WebControls.Label
IRegion " Web Form Designer
Generated Code "
'This call is required by
the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()>
Private Sub
InitializeComponent()
End Sub
Private Sub Page_Init(ByVal
sender
As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call
is required by the Web Form Designer
'Do not modify it using the
code editor. InitializeComponent()
Erid Sub
#End Region
Private Sub Page_Load(ByVal
sender As System.Object, ByVal
e As System.EventArgs)
Handles MyBase.Load
'Put user code to initialize
the page here
Dim s, t As String
Dim MyCookie As HttpCookie
MyCookie =
Request.Cookies.Item("Cookiel")
s = MyCookie.Values(0)
t = MyCookie.Values(1)
Labell.Text = "Здравствуйте,
" + s + ". Ваш последний визит на наш сайт был " + t
End Sub
End Class
Из данного листинга видно,
что основные действия производятся в обработчике page_Load, который инициируется
при загрузке Web-страницы. Заранее мы объявляем переменную MyCookie типа
HttpCookie. По умолчанию, при загрузке страницы в объект Request заранее
помещаются все cookies, связанные с данным сайтом. Так как мы точно знаем
наименование интересующего нас cookie, мы можем обратиться к нему при помощи
этого имени. Также разработчику заранее известна структура данного cookie. Мы
точно знаем, что сначала в нем записано имя пользователя, а потом дата и время
его последнего посещения сайта. Соответственно, эти данные мы читаем в строковых
переменных при помощи коллекции Values, обращаясь к этим значениям по их
порядковым номерам.
В тот момент, когда писалась
эта часть главы, европейский парламент принял решение, ограничивающее
использование сайтами технологии cookies. Свое решение парламентарии
мотивировали тем, что использование cookies позволяет собирать информацию о
действиях человека в Интернете без его ведома. Поэтому все сайты, использующие в
своей работе cookies, обязаны предупреждать пользователя, что информация о нем
будет сохранена в cookies.
Что можно сказать об этом
решении? Во-первых, следует помнить, что пользователь всегда может настроить
используемый браузер таким образом, чтобы ограничить или запретить запись
cookies в своей системе, и дополнительное напоминание может только раздражать
пользователей. Во-вторых, следует упомянуть, что только cookies позволяют
идентифицировать пользователя на сайте до того, как он зарегистрируется или
укажет свой логин, заведенный им ранее. Поэтому
отключение cookies снимет всю индивидуализацию сайта. Все настройки и
предпочтения каждого пользователя, хранящиеся именно в cookies, будут утрачены.
Таким образом, все достижения по персонализации сайтов пропадут. Ну, а
в-третьих, следует еще раз упомянуть тот факт,, что в Интернете нет
географических границ, и всегда можно найти себе хостинг вне пределов юрисдикции
европейского парламента.
Стоит ли пользователю
бояться, что данные о его работе с сайтом будут собираться, храниться и
анализироваться? Если я регулярно захожу на сайт ; туристического агентства и
просматриваю информацию о турах в Париж, сайт может "понять", что я интересуюсь
именно этой информацией, и в следующий раз, когда я зайду на сайт, предоставит
мне информацию о новых ('турах в Париж. Таким образом, я получаю информацию,
интересную именно для меня. Ничего плохого для пользователя в таком методе
работы нет. Единственный довод против использования cookies — возможность
хране-: ния в них конфиденциальной информации. Вот этого точно не стоит делать.
При помощи некоторых ухищрений и совпадении определенных условий, есть
возможность получить cookies не тому сайту или Web-приложению, которые эти
cookies сохраняли. Таким образом, если злоумышленник получает доступ к cookies
пользователя, он может прочитать информацию, хранящуюся в них. Вероятность
возникновения подобной ситуации достаточно низка, но она существует, поэтому
никогда не следует хранить в cookies конфиденциальную информацию или пароли. В
cookies может храниться лишь идентификатор пользователя и дополнительные данные
о его предыдущих посещениях. Тогда, даже в том случае, если cookie пользователя
будут получены злоумышленником, он не сможет ими воспользоваться в своих целях.
Резюмируя все вышесказанное,
следует отметить, что технология cookies при соблюдении некоторых вполне здравых
условий приносит разработчику сайта очень ощутимые выгоды и добавляет
возможности пользователю. Поэтому все-таки без cookies в хорошем сайте не
обойтись.
Следующий
урок
|