A348 Visitor Data - Hidden Variables and Cookies |
Modified:
|
Web servers are generally stateless. One problem with the stateless nature of Web servers is that no previous information about the client browser state is held by the server. Though it greatly simplifies the server design, it means that the server remembers nothing from one connection to the next; each new page or refresh makes a new connection to the server. If you were playing a Tic-Tac-Toe game on a server, the server needs information about the current state of the game (i.e. the board positions occupied). In stateless operation, the server starts each connection anew, so would always be starting a fresh game unless the game state were supplied by the browser.
For the Tic-Tac-Toe game state, the browser might hold the board and player state information, sending with each move to the server. The URL with player x in board position 1, o in board positions 4 and 5, and player x moving to position 3 might appear as:
tictactoe.asp?board=0x23oo78&x=3
With the browser client holding the state, the server can remain stateless, receiving the current game state each time the browser connects and sends the game state of: board=0x23oo78&x=3 in the URL.
Hidden variables provide one means for the client to hold and send state to the server. Hidden variables are basically the same as buttons, text, etc. except the browser doesn't display, they're hidden. Recall that user input can be sent from the browser text and button entries using the GET or POST form methods. For example, the HTML of
| <form action="http://localhost/CGI/tictactoe.exe" method="GET">
<input type="text" name="move" size=2> |
displays a text box of 2 characters in the browser. Typing 4 into the text box and pressing Enter executes the http://localhost/CGI/tictactoe.exe action and GETs 4 as standard input of move=4.
Hidden variables are data held by the browser client and returned to the server
through the GET or POST form method just as a variable that is not hidden. What
differs is that nothing is displayed by the browser, no text or buttons, and a value
is assigned the variable in the HTML. For example, the HTML of:
| <form action="http://localhost/CGI/tictactoe.exe" method="GET">
<input type="hidden" name="board" value="0x234o678"> |
displays nothing but assigns a hidden variable board = "0x234o678".
When the form is GETed the http://localhost/CGI/tictactoe.exe action
is executed and POSTs "0x234o678".
| URL
http://localhost/CGI/tictactoe.exe
<b>TicTacToe</b><br>
|
TicTacToe source code
|
Before discussing cookies, a discussion of the server is necessary. Recall the
typical communication between a browser client and a Web server.

Because the server is stateless, it maintains no data about a client between connections, effectively forgetting about the client. We have seen that user data can be maintained in a database on the server but that the user is required to identify themselves, perhaps by logging into the server. We've also seen that hidden variables can be used to maintain data temporarily on the page loaded by the client. Using a server database to maintain long-term data, hidden variables to maintain short-term data, and logins to provide initial user identification, state-full systems can be implemented.
Cookies provide a easy, simple method for maintaining state, and are often used in combination with the server database, hidden variables, and user login. Cookies consist of data stored at the behest of the server by the browser on the client's file-system and can be retrieved by the server through the client. A complete specification is at http://www.netscape.com/newsref/std/cookie_spec.html.
In contrast to hidden variables, which only exist as long as the browser holds the HTML page, cookies are relatively long lived, stored on the client file-system. Typically, the server stores a cookie on the client machine during the first visit, to read and possibly update the cookie data on subsequent visits. Because cookies are stored on a client file-system, the cookie is only available through that computer, so someone using multiple machines for logging into a system would need to go through the login process again on other clients to provide initial identification and create a cookie on each client.
Sending a cookie
The cookie is sent by the browser whenever a URL in the cookie domain is accessed. For example, the following is the full request sent from a browser to www.google.com which had previously stored a cookie.
| GET /search?hl=en&lr=&ie=UTF-8&oe=UTF-8&q=babble HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */* Accept-Language: en-us Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705) Host: www.google.com Connection: Keep-Alive Cookie: PREF=ID=6badbe492bad4u60:TM=1055825476:LM=1055825476:S=PY-bEWHY-ONOTSPY |
Receiving a cookie
The partial server response sends a new cookie for the domain google.com meaning that the browser should send the cookie whenever contacting any URL in that domain.
| HTTP/1.1 200 OK Cache-control: private Content-Type: text/html Set-Cookie: PREF=ID=6badbe492bad4u60:TM=1073216819:LM=1073216819:S=X60DAR7nmCtEjlxa; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com Server: GWS/2.1 Transfer-Encoding: chunkedDate: Mon, 19 Jan 2004 16:40:19 GMT |
Storing cookies
Netscape stored cookies in a file named cookie.txt in the c:\Program Files\NetScape\Users\name directory where name is the user name.
Internet Explorer stores cookies in directory C:\Documents and Settings\username\Cookies where each cookie is a separate file named similar to: ray@google[1].txt
Netscape
The format of the fields generally follows:
|
# Netscape HTTP Cookie File # http://www.netscape.com/newsref/std/cookie_spec.html # This is a generated file! Do not edit. www.southwest.com TRUE /cgi-bin TRUE 1016513978 resPurchasePage &CC_FIRSTNAME=Raymond&CC_LASTNAME=Wisman localhost FALSE /A348/Cookies FALSE 955670399 A348Student Ray .cheaptickets.com TRUE / FALSE 1135987200 referrer http%3A//www2.travelocity.com/LastMinuteDeals/ www.ticketmaster.com FALSE / FALSE 2145801577 NGUserID cf5834ce-235-954257833-1 .amazon.com TRUE / FALSE 955439972 session-id 104-2727763-7122841 www.perlscripters.com FALSE / FALSE 1293753514 WEBTRENDS_ID 149.160.29.92-2415653776.29335619 |
Internet Explorer
The files includes variables and data defined by the browser and server, most of which is encoded and not obviously readable:
PREF ID=74502d5f99c8b0f7:TM=1117665947:LM=1117665947:S=hUnqRK_Aj9wghDLM google.com/ 1536 2618878336 32111634 2806618384 29714171 * |
Cookies are text information stored on the browser by a the server or client JavaScript for temporarily or for a specified amount of time. Cookies are often used to personalize visits but not always reliable when several people use one machine.
The following sets the temporary WHO cookie to Ray.
<a href="" onClick='document.cookie = "WHO=Ray;"; return false;'> Set Cookie</a>
<a href="" onClick='document.write(document.cookie); return false;'> See Cookie</a>
<script language="JavaScript">
var theCookie = unescape(document.cookie); // Read cookie and find WHO
var start = theCookie.indexOf("WHO=")+"WHO=".length;
var end = theCookie.indexOf(";",start);
if(end==-1) end=theCookie.length;
document.write("Hello "+theCookie.substring(start,end));
</script>
Cookies are set from within a HTTP request, before the Content-type header. The minimal information sent is:
|
An example of setting a cookie with A348Student=Ray is given below. Note that the path that is stored with the cookie is the server URL path. If the paths differ, then more than one cookie is created and stored, if a cookie already exists it is replaced. Only CGIs or ASPs located in that original path can receive that cookie from the browser.
| URL
http://localhost/CGI/SendCookie.pl Perl SendCookie.pl program print << "EndOfHeader"; <H1>A cookie has been sent to your machine.</H1>
Set-Cookie: A348Student=Ray; expires=Thursday, 13-June-2004 23:59:59
<H1>A cookie has been set on your machine.</H1>
localhost FALSE /CGI FALSE 955670399 A348Student Ray |
ASP - The effect of setting a cookie is the same in any language. ASP Response.Cookies can set a cookie. One point of note, the cookie must be written before the <HTML> tag, since the cookie is written before the Content-type of the HTTP header.
| URL
http://localhost/A348/SendCookie.asp ASP SendCookie.Asp <%@ LANGUAGE = JScript %>
Set-Cookie: A348Student=Ray; expires=Thursday, 13-June-2004 23:59:59
<H1>A cookie has been set on your machine.</H1>
A348Student |
As noted, unless a different domain path was designated when the cookie was created, cookies are sent from the browser to a CGI or ASP in the original path.
To receive the cookie, the GetCookie.asp program must be in the same path from which the cookie was originally created.
The browser returns all cookies that were sent from that path, regardless of the requesting program. The cookies are sent as a list in the environment variable name HTTP_COOKIES. The receiving program must then parse the HTTP_COOKIE list of returned cookies to locate the one of interest.
ASP - ASP Request.Cookie can get a cookie value. To get the value of the cookie set in the above example is trivial.
| GetCookie.Asp
<%@ LANGUAGE = JScript %> |
| Browser output
Cookie value of A348Student is Ray |
| URL
http://localhost/CGI/GetCookie.pl
A348Student=Ray
HTTP_COOKIE=A348Student=Ray |
Perl GetCookie.pl program
print << "EndOfHeader"; |
| <%@ Language=JavaScript%> <% for(i=1; i<=Request.ServerVariables.Count(); i++) { strKeyName = Request.ServerVariables.Key(i); strKeyValue = Request.ServerVariables.Item(strKeyName); Response.Write( i + " " + strKeyName + "=" + strKeyValue + "<br>"); } %> |
Output (partial) HTTP_HOST=localhost HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) HTTP_COOKIE=A348Student=Ray; ASPSESSIONIDCCRABSCB=HFBBDMDCHHONCBPDCFICGGFF |
Example - A more realistic example gathers SSN user information and stores as a cookie. Later, when the user visits the site again, the SSN cookie is used to lookup the name of the person from the EMPLOYEE database.
| HTML
<TITLE>Win BIG Money</TITLE> <FORM Method='GET' ASP to send cookie - http://localhost/A348/SSNsend.asp <%@ Language=JavaScript%>
SSN Cookie stored by NetScape localhost FALSE /CGI FALSE 955670399 SSN 999887777 |
URL to execute ASP to get SSN cookie
http://localhost/A348/SSNget.asp ASP to get SSN cookie - http://localhost/A348/SSNget.asp
|
Exercise 4 - StateCookies offers a means to maintain state, similar to an exercise from Client Side Programming Exercise 3 - URL State. Create a modulus 4 counter using a cookie.
<A HREF="Exercise3.Asp"><IMG SRC="digit0.gif"></A> ) when the digit image is clicked. Some JavaScript for handling cookies:
|