ASP - Управление сеансами
Важнейшая задача, которую приходится решать при создании веб-приложений, это сохранение относящихся к пользователю сведений за весь сеанс его работы, в то время как сам пользователь может свободно перемещаться между страницами приложения. Протокол HTTP является протоколом без состояний, то есть каждый HTTP-запрос для страницы обрабатывается веб-сервером независимо. Таким образом, сервер не сохраняет сведений о предшествующих запросах, независимо от того, насколько малы промежутки времени между ними. Эта особенность затрудняет создание некоторых приложений, например интерактивного каталога, где необходимо сохранять сведения о выбираемых пользователем элементах каталога при его перемещении между страницами каталога.
В ASP обеспечено уникальное решение вопроса управления данными сеанса. Используя объект ASP Session (сеанс) и особый код пользователя, который автоматически формируется сервером, можно создавать «умные» приложения, которые будут автоматически узнавать каждого посетителя узла и собирать необходимые сведения о его предпочтениях или выбираемых им вариантах.
Важно! Код пользователя назначается в ASP посредством HTTP-модуля настройки, небольшого по объему файла, который сохраняется в обозревателе пользователя. Таким образом, при создании приложений для работы с программами обозревателя, в которых описанные модули настройки не поддерживаются или отключены пользователем, средства управления сеансами ASP задействовать не следует.
Начало и завершение сеансов
Существует четыре варианта начала сеанса.
- Новый пользователь запрашивает адрес URL, который указывает на файл «.asp» в приложении, а файл Global.asa для данного приложения содержит процедуру Session_OnStart.
- Пользователь сохраняет значение в объекте Session.
- Новый сеанс запускается автоматически при получении сервером запроса без требуемого модуля настройки SessionID.
- Пользователь в приложении запрашивает файл «.asp», а в файле приложения Global.asa при создании экземпляра объекта с областью действия на уровне сеанса используется тег <OBJECT>. Дополнительные сведения о создании экземпляра объекта с помощью тега <OBJECT> можно найти в разделе Использование компонентов и объектов.
Сеанс автоматически завершается, если пользователь в приложении не запросил или не обновил страницу в течение определенного периода времени. По умолчанию этот период составляет 20 минут. Используемое по умолчанию значение для приложения можно изменить с помощью свойства Session Timeout (время ожидания сеанса) на листе свойств Параметры приложения в оснастке IIS. Это значение должно определяться с учетом потребностей веб-приложения и объема памяти сервера. Так, если ожидается, что посетители будут уделять каждой странице веб-приложения всего несколько минут, установленное по умолчанию время ожидания сеанса можно значительно сократить. Если время ожидания велико, число одновременно открытых сеансов может значительно увеличиться, что отрицательно скажется на свободных ресурсах оперативной памяти сервера.
Уменьшая указанное по умолчанию время ожидания сеанса, можно одновременно задать свойство Timeout (ожидание) для объекта Session (сеанс). Например, в следующем сценарии устанавливается период ожидания продолжительностью в 5 минут.
<% Session.Timeout = 5 %>
Кроме того, можно установить период ожидания, который превышает используемое по умолчанию значение, определяемое свойством Session Timeout (время ожидания сеанса).
Примечание. Свойство Timeout (время ожидания) применимо только к сеансам с состояниями. На протяжении сеансов без состояний объект Session (сеанс) не включает в себя статических объектов или содержимого. Подобные сеансы автоматически завершаются после обработки запроса и его последующего возобновления в связи с поступлением нового запроса от того же обозревателя.
Для принудительного завершения сеанса существует метод Abandon (завершение) объекта Session (сеанс). Например, в форму можно поместить кнопку «Выход», а в качестве параметра ACTION указать URL файла «.asp» со следующей командой.
<% Session.Abandon %>
Примечание. Пользовательские запросы, которые были помещены в очередь до запуска команды Session.Abandon, выполняются в контексте завершаемого сеанса. После выполнения команды Session.Abandon вновь поступающие запросы уже не будут связаны с данным сеансом.
О коде сеанса и модулях настройки
При первом поступлении пользовательского запроса на файл «.asp» в данном приложении ASP создает SessionID (код сеанса). Это число рассчитывается по сложному алгоритму и позволяет однозначно определить каждый сеанс пользователя. В начале нового сеанса сервер сохраняет этот код в обозревателе пользователя как файл модуля настройки узла.
Модуль настройки SessionID подобен коду к сейфу: в сеансе взаимодействия пользователя с приложением ASP может сохранять относящиеся к пользователю сведения в специально отведенном месте на сервере. Содержащийся в модуле настройки код сеанса пользователя преобразуется в заголовок HTTP-запроса. Это открывает доступ к сведениям, как открывается сейф после набора правильного шифра замка. Получая запрос на страницу, ASP всегда проверяет код сеанса в заголовке HTTP-запроса.
Сохраненный в обозревателе пользователя код используется ASP на протяжении всего сеанса, даже если пользователь запрашивает другой файл «.asp» или файл «.asp» из другого приложения. Если сеанс принудительно завершается пользователем или оканчивается по истечении периода ожидания, при запросе другого файла «.asp» ASP начинает новый сеанс с тем же кодом. Выделение пользователю нового кода сеанса имеет место только при перезапуске сервера администратором, поскольку это очищает хранящиеся в памяти параметры SessionID, или в результате перезапуска обозревателя на компьютере пользователя.
Использование одного и того же кода сеанса позволяет ASP уменьшить число передаваемых в обозреватель модулей настройки. Кроме того, если было указано, приложению ASP не требуются средства управления сеансом, можно отключить журнал сеанса в ASP и отправку модулей настройки SessionID пользователям.
ASP не отправляет модуль настройки сеанса в следующих случаях.
- Отключено сохранение сведений о состоянии сеанса в приложении.
- Страница ASP определена как не сохраняющая сведений о сеансе, то есть содержит тег
<%@ EnableSessionState=False %>
. Дополнительные сведения см. в разделе Страницы ASP без сеансов.
Следует учитывать, что модули настройки SessionID не предназначены для постоянного наблюдения за работой пользователей на протяжении многократных посещений ими веб-узла. Данные модуля настройки SessionID хранятся в оперативной памяти сервера и легко могут быть потеряны. Чтобы сохранять сведения о посетителях веб-приложения за более продолжительный срок, следует сохранить на компьютере пользователя особый модуль настройки и занести в базу данных сведения, которые дают возможность опознать пользователя впоследствии. Дополнительные сведения см. в разделе Использование модулей настройки «cookie».
Сохранение и удаление данных из объекта Session
Объект Session обеспечивает доступ к динамическому массиву с ассоциативными связями, предназначенному для хранения соответствующих данных. В объекте Session могут храниться как скалярные, так и объектные переменные.
Для сохранения переменной в объекте Session следует присвоить значение поименованной записи объекта Session. Ниже приводится пример команды сохранения двух новых переменных в объекте Session.
<% Session("FirstName") = "Михаил" Session("LastName") = "Петров" %>
Извлечение данных объекта Session осуществляется посредством обращения к соответствующей поименованной записи. Например, для просмотра текущего значения переменной Session("FirstName") служит следующая команда.
Welcome <%= Session("FirstName") %>
Объект Session позволяет также сохранить сведения о предпочтениях пользователя, на основании которых впоследствии можно будет определить, какую страницу следует ему отправить. Так, если на первой странице приложения пользователем выбирается текстовое представление сведений, та же форма представления может использоваться применительно к остальным страницам приложения, которые он посетит.
<% If Session("ScreenResolution") = "Low" Then %> Текстовая версия страницы. <% Else %> Мультимедийная версия страницы. <% End If %>
В объекте Session можно также сохранить экземпляр объекта, хотя это может сказаться на быстродействии сервера. Для получения дополнительных сведений см. раздел Задание области определения объекта.
Иногда хранящиеся в объекте Session элементы нужно удалить. Например, нередки случаи, когда посетители электронного магазина отказываются от уже выбранных товаров и составляют новый список покупок. В этих обстоятельствах может оказаться целесообразным обновление объекта Session с удалением лишних элементов.
Семейство Contents объекта Session содержит все хранящиеся переменные сеанса (речь идет о переменных, для сохранения которых не используется тег <OBJECT> языка HTML). С помощью метода Remove семейства Contents можно выборочно удалить ссылки на переменные, которые добавлялись при соответствующем состоянии сеанса. Следующий сценарий иллюстрирует применение метода Remove для очистки элемента (в данном случае это сведения о предоставляемых пользователю скидках), из объекта Session.
<% If Session.Contents("Purchamnt") <= 75 then Session.Contents.Remove("Discount") End If %>
При необходимости полностью удалить все сохраняемые переменные сеанса можно с помощью метода RemoveAll семейства Contents.
Session.Content.RemoveAll()Для метода Remove имеется возможность выбрать удаление элементов по именам или по индексу. В следующем сценарии показан пример циклического перебора значений объекта Session и их удаление по индексу при выполнении заданного условия.
<% For Each intQuote in Session.Contents If Session.Contents("Purchamnt") <= 200 then Session.Contents.Remove(intQuote) End If Next %>
Использование модулей настройки («cookie»)
Модуль настройки (файл «cookie») представляет собой опознавательную метку, которая внедряется веб-сервером в обозреватель пользователя. При очередном запросе веб-страницы обозреватель отправляет на сервер полученный ранее модуль настройки. Эта схема позволяет связать сведения о пользователе с конкретным посетителем. Сценарии ASP позволяют получать и устанавливать значения «cookie». Этой цели служат семейства Cookies объектов Response и Request.
Установка значений «cookie»
Установка значения «cookie» выполняется командой Response.Cookies. Если это значение ранее отсутствовало, команда Response.Cookies создаст новое значение. Так, для отправки обозревателю модуля настройки с именем ("VisitorID") и значением ("49") можно воспользоваться следующей командой, которая на веб-странице должна располагаться до тега <HTML>.
<% Response.Cookies("VisitorID") = 49 %>
Если продолжительность действия модуля настройки должна ограничиваться только текущим сеансом, отправки этого модуля в обозреватель вполне достаточно. Но если стоит задача опознания посетителя даже после перезапуска обозревателя, модуль настройки «cookie» должен быть сохранен обозревателем в виде файла на жестком диске компьютера пользователя. Для сохранения модуля настройки используйте в Response.Cookies атрибут Expires с будущей датой.
<% Response.Cookies("VisitorID") = 49 Response.Cookies("VisitorID").Expires = "December 31, 2001" %>
Модуль настройки может принимать сразу несколько значений, например индексированный модуль настройки. Индексированному модулю настройки назначается ключ, которому может быть присвоено определенное значение. Пример.
<% Response.Cookies("VisitorID")("49") = "Travel" %>
Если существующий модуль настройки уже имеет значения ключа, однако имя ключа в Response.Cookies не определено, значения ключа удаляются. Если же существующий модуль настройки не имеет значений ключа, а Response.Cookies определяет имена и значения ключа, существующее значение «cookie» удаляется. При этом создаются новые пары «ключ-значение».
Получение значений «cookie»
Для получения значения «cookie» служит семейство Request.Cookies. Например, если HTTP-запрос пользователя задает VisitorID=49
, значение 49
может быть извлечено следующей инструкцией.
<%= Request.Cookies("VisitorID") %>
Точно так же значение ключа из индексированного модуля настройки может быть получено по имени ключа. Например, обозреватель пользователя отправляет в заголовке HTTP-запроса следующие данные:
Cookie: VisitorID=49=Travel
Показанная ниже инструкция возвратит значение Travel
.
<%= Request.Cookies("VisitorID")("49") %>
Определение путей в модуле настройки
Все модули настройки, которые сохраняются ASP в обозревателе пользователя, содержат сведения о пути. Запрашивая файл, путь которого указан в модуле настройки, обозреватель автоматически направляет этот модуль на сервер. По умолчанию сохраненные в модуле настройки пути соответствуют имени приложения с файлом «.asp», с помощью которых был создан данный модуль настройки. Так, после создания модуля настройки с помощью файла «.asp», который относится к приложению с именем UserApplication, каждое последующее обращение веб-обозревателя пользователя к любому файлу данного приложения будет сопровождаться отправкой соответствующего модуля настройки. Будут отправляться также все остальные модули настройки, содержащие путь /UserApplication.
Чтобы задать в модуле настройки путь, отличный от используемого по умолчанию пути приложения, можно воспользоваться атрибутом Path семейства ASP Response.Cookies. Например, в следующем сценарии путь SalesApp/Customer/Profiles/ назначается модулю настройки Purchases
.
<% Response.Cookies("Purchases") = "12" Response.Cookies("Purchases").Expires = "January 1, 2001" Response.Cookies("Purchases").Path = "/SalesApp/Customer/Profiles/" %>
Каждый раз, запрашивая файл из /SalesApp/Customer/Profiles/ (или из находящихся по этому пути каталогов), веб-обозреватель, в котором содержится модуль настройки Purchases
, отправляет этот модуль настройки на сервер.
При сохранении пути модуля настройки многие обозреватели, в числе которых Microsoft Internet Explorer (версия 4.0 и более поздние), а также обозреватели Netscape, различают регистр букв. Это означает, что если регистр букв пути, который указывается в запросе, и пути, который был сохранен в модуле настройки, отличается, обозреватель не выполняет отправку модуля настройки на сервер. Например, для ASP, виртуальные каталоги /TRAVEL и /travel одинаковы, однако с точки зрения обозревателя, который различает регистр букв в адресе URL, /TRAVEL и /travel указывают на разные приложения. Поэтому необходимо следить за тем, чтобы все адреса URL для файлов «.asp» задавались в одном регистре. Это гарантирует отправку обозревателем сохраненных модулей настройки на сервер.
Чтобы определить путь, при котором модуль настройки будет отправляться обозревателем на сервер одновременно с запросом файла, независимо от пути или приложения, можно воспользоваться следующей инструкцией.
Response.Cookies("Purchases").Path = "/"
Однако следует помнить, что независящая от приложения отправка модуля настройки на сервер может привести к снижению уровня безопасности, если модуль настройки содержит данные, доступ к которым должен быть разрешен только в пределах конкретного приложения.
Сохранение сведений о состоянии без помощи модулей настройки
Работу с модулями настройки поддерживают не все обозреватели. Если эта поддержка имеется, она также может быть отключена пользователем. Если требуется обеспечить совместимость приложения с обозревателями, не поддерживающими модули настройки, возможности управления сеансами ASP задействовать не следует.
В этом случае необходимо разработать собственную схему передачи сведений между страницами приложения. Это может быть сделано двумя основными способами.
- Добавление параметров в строку запроса URL. Пример.
http://MyServer/MyApp/start.asp?name=Jeff
Однако в некоторых обозревателях при передаче формы с использованием метода GET параметры, которые явно передаются в строке запроса могут не обрабатываться.
<FORM METHOD="POST" ACTION="/scripts/inform.asp"> <INPUT TYPE="text" NAME="city" VALUE=""> <INPUT TYPE="text" NAME="country" VALUE =""> <INPUT TYPE="hidden" NAME="userid" VALUE= <%= UserIDNum(i) %> <INPUT TYPE="submit" VALUE="Enter">
Данный метод требует, чтобы все ссылки на сведения пользователя указывали на HTML-формы.
Если управление сеансами ASP не используется, поддержку сеансов в приложении следует отключить. Если сеансы включены, в ответ на каждый запрос страницы обозревателем ASP отправляет модуль настройки SessionID. Чтобы отключить поддержку сеансов, очистите флажок Включить состояние сеанса на листе свойств Параметры приложения в оснастке IIS.
Страницы ASP без сеансов
В ASP существует также возможность создания страниц без сеансов. Это позволяет создавать сеансы только по мере надобности.
В страницах без сеансов отсутствуют следующие возможности.
- Выполнение процедур Session_OnStart.
- Отправка модулей настройки с кодами сеансов.
- Создание объектов Session.
- Доступ к встроенным объектам Session или объектов, действующих на уровне сеанса, для создания которых использовался тег <OBJECT>.
- Последовательное выполнение вместе с другими запросами сеанса.
Чтобы настроить файл «.asp» без сеансов, воспользуйтесь следующей инструкцией.
<%@ EnableSessionState=False %>
Эта строка сценария должна идти в файле «.asp» первой, предшествуя остальным сценариям. По умолчанию (если этот тег опущен) сохранение данных сеансов включено.
Страницы ASP без сеансов могут повысить скорость ответов сервера, поскольку в этом случае нет потерь времени на обработку сведений о сеансах. Рассмотрим, например, страницу ASP с двумя HTML-рамками, с номерами 1 и 2, расположенными в пределах одной группы рамок. Рамка 1 содержит файл «.asp», в котором выполняется сложный сценарий. Рамка 2 содержит более простой файл «.asp». Поскольку ASP выполняет запросы сеансов по порядку, или последовательно, просмотр содержимого рамки 2 будет возможен только после выполнения сценария рамки 1. Однако если файл «.asp» рамки 1 не поддерживает сведения о сеансах, последовательный порядок выполнения запросов ASP не требуется, поэтому содержимое рамки 2 может быть отображено еще до завершения сценария рамки 1.
К сожалению, порядок выполнения группы запросов для различных рамок зависит от настроек применяемого пользователем обозревателя. Отдельные версии обозревателей могут также придерживаться последовательной обработки запросов независимо от поддержки сеансов, которая была установлена в файлах «.asp».