

ASP ADVANCED

Sessions
were invented to address a limitation of the HTTP protocol.
Remember how the HTTP protocol works--whenever a user makes a
request, the server supplies a response.
All interaction between a browser and a Web server takes place in
discrete request and response pairs.
Nothing
in the HTTP protocol allows a server to keep track of the users making the
requests. After a server has
finished responding to a request, the server can't continue to identify
the browser that made it. From
the perspective of a Web server, each new request is made by a new
individual. For this reason,
the HTTP protocol is called a stateless protocol. The
HTTP protocol can't be used to retain the state of a user.
This is a very serious limitation because it means that you can't
identify a user over multiple Web pages.
Sessions
were introduced to fix this problem.
By using sessions, you can store information about
a user over multiple Web pages. Sessions
allow you to do many things that would otherwise be very difficult or
completely impossible.
Storing
Session Information
Active
Server Pages sessions are very easy to use.
You can control all aspects of a session by using the active Server
Pages session object. If you
need to store data that will persist through out a user session, you
simply store that data in a collection of the session object.
Here's an example:
<HTML>
<HEAD><TITLE> Session Example</TITLE></HEAD>
<BODY>
<%
Session("Greeting")="Welcome!"
Response.Write(Session("Greeting"))
%>
</BODY>
</HTML>
When
this Active Server Page is displayed in a browser, the greeting welcome!
is displayed.The first line in this script assigns the text "Welcome!
" to a session variable named Greeting.
The next line in the script outputs the greeting to the screen.
So
far, this isn't particularly exciting.
You can do the same thing by using a normal VBScript variable.
However, imagine that the same user requests another page.
For example, imagine that the user requests the following page:
<HTML>
<HEAD><TITLE> Another Page </TITLE></HEAD>
<BODY>
<%=Session("Greeting")%>
</BODY>
</HTML>
When
the user views this page, the same welcome! greeting is displayed once
again. However, the session
variable wasn't assigned a value on this page.
The session variable Greeting has retained the value it was
assigned on the previous page.
You
couldn't do this with a normal script variable.
The lifetime of a normal variable extends only throughout a single
page. A session variable, on
the other hand, persists until the user leaves the Web site.
It's
important to understand that session variables exist only in relation to a
particular user. The values
assigned to session variables in one user session don't affect the values
of the session
variables in another user session. In
other words, the data stored in session variables isn't shared among
different users. For
example, suppose the following script appeared in an Active Server Page:
<%
Randomize
if INT(2*RND)=1 THEN
Session("FavoriteColor")="Blue"
ELSE
Session("FavoriteColor")="Red"
END IF
%>
This
script randomly assigns the session variable FavoriteColor with either the
value "Blue" or the value "Red".
This variable may have a different value in the case of different
users. The value of the
variable FavoriteColor is relative to a particular user session.
The
Contents of a Session
Most
session variables are actually stored in a collection of the Session
object named contents. For
example, the following two statements are equivalent:
<%
Session("MyVar")="Some data" %>
<%
Session.Contents("MyVar")="Some data" %>
As
in the collections discussed previously, you can use the count property to
determine the number of items in the contents collection.
You can also display all the items contained in the contents
collection by using either a FOR ... EACH or a FOR ... NEXT loop.
This example uses both methods:
<%
Session("FavoriteColor")="blue"
Session("FavoriteFont")="Comic Sans MS"
%>
There are
<%=Session.Contents.Count %>
items in the Session contents collection.
<HR>
<%
FOR EACH thing IN Session.Contents
Response.Write( "<BR>"&thing&"="&Session.Contents(thing))
NEXT
Response.Write("<HR>")
FOR i=1 TO Session.Contents.Count
Response.Write("<BR>"&Session.Contents(i))
NEXT
%>
In
this script, two session variables named FavoriteColor and FavoriteFont
are created. Next, a count of
the number of items in the Contents collection is retrieved.
Finally, all of the items in the Contents collection are displayed
by using both a FOR... EACH and a FOR...NEXT loop (see Figure below).
The
contents of the Contents collection
ldentifying
a Session
Active
Server Pages assigns each user session a unique identifier.
This session ID is created when the user session is first created
and persists throughout the time the user remains at your Web site.
To retrieve the session ID, you use the sessionsID property of the
session object, as in this example:
<HTML>
<HEAD><TITLE> Session ID </TITLE></HEAD>
<BODY>
Your session ID is: <%=Session.SessionID
%>
</BODY>
</HTML>
The
Active Server Page here simply outputs the value of the SessionID
property. When different users retrieve the page, a different session ID
will be displayed for each. However,
if the same user retrieves the page multiple times, the same session ID
should be displayed.
One
use for the sessionsID property is to track the movements of your
visitors. For example, you
can record the pages that a user visits in the log file of your Web site.
Simply create the following file and include it in every page:
<%
Who=Session.SessionID
CurrentPage=Request.ServerVariables('SCRIPT_NAME")
Response.AppendToLog Who&":"&CurrentPage
%>
This
script uses the AppendToLog method of the Response object to append an
entry in the server log file. In
this example, the string added to the log file contains the session ID
that was retrieved from the sessionID property.
The string also contains the path to the current page, which was
retrieved from the SCRIPT_NAME server variable.
Controlling
When Sessions End
How
does the server know when a session ends?
In other words, how does the server know whether a user has left
your Web site for another one or has turned off his or her computer and
gone to see a movie?
The
server assumes that if someone hasn't requested or refreshed a page for a
period of more than 20 minutes, that person has left, and times out that
user's session. This strategy
allows the server to recover resources that it has been using to track the
user's session.
For
certain Web site applications, this timeout period of 20 minutes is too
short. For example, suppose
you have a game site that includes a number of complicated puzzles, which
the user must solve with pen and paper.
You might expect the user to be inactive, from the Web server's
perspective, for long periods of time.
For
other Web site applications, the session timeout period of 20 minutes is
too long. If you have a very
high volume Web site, and you want to ease the burden on your server as
much as possible, you may want a shorter session timeout period.
Fortunately,
you can control the maximum amount of time for which a user is allowed to
be inactive before a session.times out.
The session object has a property for this purpose.
You can set the amount of time before a session times out by using
the Timeout property of the session object.
For example, the following script sets the Timeout property to 60
minutes:
<%
Session.Timeout=60 %>
When
a user session times out and the user makes a new request, the server
treats the user as a new user. The
server creates a new session, and all the old session information is lost.
You can force this to happen manually by using the Abandon method
of the session object. Consider
the following example:
<HTML>
<HEAD><TITLE> Abandon Session </TITLE></HEAD>
<BODY>
<BR>The user is <%=Session.SessionID %>.
<% Session.Abandon %>
<BR>The user is <%=Session.SessionID %>.
</BODY>
</HTML>
In
this example, the session ID of the user is outputted to the screen.
Next, the Session.Abandon method is called.
When the user ID is outputted once again, the ID is a different
number. After the Abandon
method is called, the server treats the user as a new user (see Figure
below).
Abandoning
a session
Session
Events
Unlike
any of the other objects discussed to this point, the session object has
events. Two of them, in fact:
the Session_OnStart event, which is triggered when a session begins, and
the Session_OnEnd event, which is triggered when a session ends.
You can associate one and only one script with each of these two
events.
The
statements in the script are executed when the event is triggered.
Both of these scripts must be located in a special file named
Global.asa. Every Web site
application can have only one Global.asa file.
The file is located in the root directory of your Web site
application. It contains
information that's global to your Web site application.
The Global.asa file has the following structure:
<SCRIPT
LANGUAGE=VBScript RUNAT=Server>
SUB Application_OnStart
END SUB
</SCRIPT>
<SCRIPT
LANGUAGE=VBScript RUNAT=Server>
SUB Application_OnEnd
END SUB
</SCRIPT>
<SCRIPT
LANGUAGE=VBScript RUNAT=Server>
SUB Session_OnStart
END SUB
</SCRIPT>
<SCRIPT
LANGUAGE=VBScript RUNAT=Server>
SUB Session_OnEnd
END SUB
</SCRIPT>
The
Global.asa file can contain four scripts.
One of these scripts is triggered by the Session_OnStart event and
one is triggered by the session_OnEnd event. (The next chapter covers the
two remaining scripts.)
Notice
that Global.asa uses the Microsoft extended HTML<SCRIPT> tag syntax
to specify the scripts. You
must use this method of indicating a script within the Global.asa file
instead of
Using the normal script delimiters <% and %>. The Global.asa file in
the preceding example uses VBScript as the scripting Ianguage, but you can
use other scripting languages as well.
You
can't include any output within the Global.asa file.
In particular, you can't use any HTML tags or the Response.Write (
) method. The Global.asa file
itself is never displayed. The
file is used only to contain scripts and objects.
To
create a script that executes whenever a new session is started, you
simply add the script to the Session_OnStart section of the Global.asa
file, as in this example:
<SCRIPT
LANGUAGE=VBScript RUNAT=Server>
SUB Session_OnStart
Session("UserName")="Unknown"
Session("UserPassword")="Unknown"
END SUB
</SCRIPT>
This
script assigns the value "Unknown" to two session variables
named username and UserPassword. This
example illustrates one of the main functions of the session_onstart
script-initializing session variables.
The
Session_OnStart script can be used for other purposes as well.
For example, one interesting application of the session_onstart
script is for redirecting visitors to a new page.
Suppose you don't want any visitors of your Web site to go directly
to any page other than the home page when they first arrive.
You can redirect the first page request to the home page by using
the Response.Redirect method. Here's
an example:
<SCRIPT
LANGUAGE=VBscript RUNAT=Server>
SUB Session_OnStart
MyHomePage="/homepage.asp"
RequestPage=Request.serverVariables("SCRIPT_NAME")
IF NOT (STRCOMP(MyHomePage,RequestPage,vbTextCompare)=O)THEN
Response.Redirect MyHomePage
END IF
END SUB
</SCRIPT>
In
this script, the path of the page that the user requests is compared to
the path of the home page. If
they're not the same, the user is automatically redirected to the home
page.
This
final example uses both the session_OnStart and Session_OnEnd events:
<SCRIPT
LANGUAGE=VBScript RUNAT=Server>
SUB Session_OnStart
Response.AppendToLog Session.SessionID&" starting"
END SUB
</SCRIPT>
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
SUB Session_OnEnd
Response.AppendToLog Session.SessionID&" ending"
END SUB
</SCRIPT>
The
Session_OnStart and Session_OnEnd scripts here record the session ID of
the user in the log file. Because
the session_OnStart script executes when a User first arrives, this
Session_OnStart script records when the user starts a new session.
The session_OnEnd script records when the user leaves.
You can use this information to determine the pages that are most
often used to enter and exit your Web site.
How
Sessions Really Work
Sessions
use cookies (see the following section for details on cookies).
When a user first requests a page from your Web site, the server
creates a single cookie in the user's browser to track the session.
When the session ends, the cookie expires as well.
The
cookie created for each user is named ASPSESSIONID.
The only purpose of this cookie is to provide a unique identifier
for each user.
The
session variables themselves are not stored on the user's browser.
However, the ASPSESSIONID cookie is needed to use session
variables. The server uses
the ASPSESSIONID cookie to associate the proper session variables with the
proper user. Without the
cookie, the server would have no way to identify the same user as he or
she moved from page to page on a Web site.
The
session ID stored in the ASPSESSIONID cookie is not the same as the
SessionID property. Microsoft
uses a complicated algorithm to generate the value of the ASPSESSIONID
cookie. Microsoft does this
in order to prevent hackers from guessing the session ID and pretending to
be someone they're not.
Because
the Session object uses cookies, the object may be incompatible with both
old and very recent browsers. Older
browsers simply can't use cookies. What's
even worse, many very recent browsers, such as Netscape 4.0, provide the
option of disabling cookies altogether.
This
presents a problem. Because
cookies aren't compatible with all browsers, you should be cautious in
using the Session object when building your Website. Although there are
certain things that you simply can't do without using sessions, certain
properties of a session can be simulated by other means.
Some alternatives to using cookies and the Session object are
discussed in the later section "Retaining State Without
Cookies."
|