The whole concept of Applications
and Sessions
requires the browser to accept and implement cookies. If it doesn't, then ASP is unable to maintain state information of any kind. We have to resort to the older methods of CGI programming.
As we said earlier, the HTTP protocol is inherently stateless, and relies on cookies to be able to manage and recognize requests, and match them to the users. When ASP wants to establish a session, it sends the Set-Cookie
HTTP header to the browser, to establish a unique user session ID and the path of the application it corresponds to—i.e. where the appropriate global.asa
file resides:
Set-Cookie: ASPSESSIONID=LRUSDYXQMWRTNWEB; path=/TestApp
From our discussions of cookies in Chapter 2, you'll realize that this one doesn't expire until the browser is shut down. In theory, if the browser was to be left running for weeks on end, the cookie will remain current. But the Session
object has a default Timeout
of twenty minutes, and that point the Session
is marked as having ended and any variables in it are destroyed.
The fact that a user's Session
ID
cookie may not have expired, while the matching Session
on the server already has expired, raises an interesting question. What happens if that user comes back to our site again? The server will check the session ID in their cookie against the currently active sessions, and if it doesn't match will just create and initialize a new Session
. The user then effectively 'goes back to the start'.
Of course, this assumes that the session ID will be unique for every user. If this isn't the case, the application might find itself with two users sharing a Session
. We have to assume that Microsoft has thought of this, and that the session ID generator is sufficiently random to prevent it happening!
One problem that Microsoft cannot prevent is the situation where the session ID cookie our server sends is not supported by the browser, or not accepted by the user. Or more critically, it's possible for the server administrator to turn off the ability to maintain Sessions altogether by editing the registry. Now, the automatic state mechanism is not going to work, so we need an alternative plan.
We could use a system originally implemented in ASP, but then removed again, which added parameters to all the hyperlinks in the pages so as to pass on the session ID. We could emulate this, or just shunt the user off to a separate version of our site that worked without requiring state information. We could even throw them out altogether, though this may tend to discourage future visits...
But before we can do any of this, we need a way of determining whether or not the browser can support cookies, without causing havoc. Easy enough, we just use a default opening page that gets sent to every user, when they first enter the application. We could include a 'Welcome' graphic, like a real application's splash screen, or possibly some introduction to the site:
Here's the code that creates this page, with the important lines are highlighted:
<HTML>
<HEAD>
<META HTTP-EQUIV="REFRESH" CONTENT="5; URL=hellotest.asp">
<TITLE>Document Title</TITLE>
</HEAD>
<BODY>
<CENTER><IMG SRC="Welcome.gif"></CENTER>
<% On Error Resume Next
Session("TestBrowser")="Hello" %>
</BODY>
</HTML>
The ASP code first turns off error checking, then stores a value in a Session
level variable named TestBrowser
. If the browser doesn’t support cookies, or if they're turned off, there will be no Session
object and the code will fail—however there won't be an error message because of the On
Error
Resume
Next
. The real key to this page is the first highlighted line:
<META HTTP-EQUIV="REFRESH" CONTENT="5; URL=hellotest.asp">
Once the page has finished loading, the browser waits five seconds and then loads the page hellotest.asp
—which contains this code, placed before the <HEAD>
section:
<% On Error Resume Next
If IsEmpty(Session("TestBrowser")) Then
Response.Redirect "NoCookie.asp"
Else
Response.Redirect "AllowCookie.asp"
End If %>
<HTML>
<HEAD>
...
All it does is check the value of the TestBrowser
variable. If it's Empty
we know that the browser, for one reason or another, doesn't have the ability to use a Session
—which is likely to be because it can't (or won't) support our session ID cookies. If this is the case we just redirect the visitor to a page that is intended for non-session ASP users. Otherwise its business as usual, and we redirect them to the main menu of our application. Notice that it's necessary to wrap the If
statement in another On
Error
Resume
Next
, in case the IsEmpty
test fails. If it does, the next statement to be executed still sends them to the non-session area of the site.
The code we've seen in the previous section is an excellent example of the way that we can redirect users to a different page at will. We can often take advantage of this method to route users through an application, depending on the current state for that user, or the application as a whole.
For example, we might allow them to chose goods they want to purchase, in a kind of virtual shopping trolley. Each time they click the Yes, I Want One button, we add the details to our Session
object, using an array like we saw earlier:
Sub cmdYesIWantOne_onClick
'Retrieve the array and current item count from the Session object ...
LocalArray = Session("BoughtItems")
intNumberOfItems = CInt(Session("ItemCount")) + 1
LocalArray(intNumberOfItems) = strItemCodeNumber
'then store the updated values back again.
Session("BoughtItems") = LocalArray
Session("ItemCount") = CStr(intNumberOfItems)
End Sub
When they've finished shopping, and click the All Done Now button, we only need to route them to the virtual checkout if they have actually bought anything. It's easy using document redirection:
If CInt(Session("ItemCount")) > 0 Then
Response.Redirect "cashdesk.asp"
Else
Response.Redirect "thankyou.asp"
End If
Doing a redirection like the last example is only possible from the header of a document, before any content has been sent to the browser. If we attempt it after that, we get a Buffer not empty error. Remember from Chapter 2 that if we want to provide an opportunity for redirection to occur part way through a page, we need to turn on buffering, and clear the buffer, first:
<%@ LANGUAGE="VBSCRIPT" %>
<% Response.Buffer = True %>
<HTML>
<HEAD><TITLE> Document Title </TITLE></HEAD>
<BODY>
<H1>Welcome to our site</H1><P>
<% If Session("TestCondition") = True Then
Response.Clear
Response.Redirect "anotherpage.asp"
End If %>
...
rest of page
...
</BODY>
</HTML>