It's nice to maintain state but cookies can be awkward or even rude.
Recently, I have been involved in a great deal of research regarding methods that can be used to maintain state throughout multiple pages of a Web-based application (or a multiple-page site). Through hours of surfing the Web, it has become clear that each of the currently proposed methods is flawed in at least one fundamental way.
September 18, 1999
Cookies:
Storing text on the client which will be passed to the application with every HTTP request.
Can be disabled by the client.
Are wrongfully perceived as "dangerous", and therefore will scare away potential site visitors if asked to enable cookies.
Hidden Fields:
Use CGI to generate pages with session identification information embedded in hidden fields. Use this method throughout the site.
Identification information becomes apparent to the user via a simple "View Source."
A killer for efficiency's sake, as all pages in the site must be built with a CGI script.
Extended Path Info:
Append identification information to the end of every link on the page via scripting. Use the PATH-INFO header to extract session identification information.
Identification information becomes even more visible, making the user worry about security risks.
May require server-side programming (I don't believe that this can be accomplished with JavaScript and the OnClick() event).
IP Address - Session ID Lookup Table:
Since an ISP user will have a consistent IP address throughout a given logon, you can use the IP address of client (passed as a part of the HTTP request) to identify the user.
Difficult to implement efficiently.
Malfunctions if multiple concurrent users are behind a proxy server/firewall.
An arbitrary timeout must limit the idle time for a session.
HTTP-FROM Header:
This header should contain a client's Internet mail address. This can be used as a unique identifier for that client.
Header unsupported by most modern browsers, including Internet Explorer and Navigator.
So, this being the case, how do we provide stable session information with as little burden on our Web server and with as little dependence upon CGI scripting as possible? I have been teased with the following responses (which each have their respective flaws):
Active Server Pages:
Session and Application objects give you exactly what you're looking for!
ASP uses cookies (or, with cookie-munching, extra PATH-INFO) to maintain state. These methods have major disadvantages noted above.
Requires ASP compatible servers (IIS, PWS), which have been shown to scale poorly.
Server-side JavaScript:
Contains the Client object for the purpose of maintaining state.
Server-side JavaScript requires the user to define which method of state maintenance to use. This is fine for applications of less than critical scope, but is never foolproof.
Requires a compatible server.
A slew of near-perfect answers, indeed. However, the business specifications for many sites will indicate that they cannot suffer from any of the limitations imposed by these methods. It may be possible to wait for a change in the HTTP protocol that includes the much-talked-about SESSION-ID header field (which would contain a unique identifier). However, this solution would likely not be backward-compatible with older browsers. There may yet be one more suitable and robust solution. The solution will perform on systems with cookies disabled, through firewalls, and through dial-up ISPs. I submit the following to you for critique and dissemination.
Client-Side State Maintenance without Cookies via a Hidden Frame:
In order to maintain state throughout a site or application, the following goals should be kept in mind.
The solution should apply to as wide an audience as possible. No one should be dissuaded from visiting a site as a result of a browser incompatibility or a refusal to use cookies.
The solution should burden the server as little as possible. Creating every page dynamically through CGI scripting can create awesome content, but it may suffer from serious performance lags.
The end user should not feel threatened by the methods employed by your site. This means not exposing sensitive information to mischievous acts and/or public display.
My solution is to "frame" your site within a FRAMESET containing two frames, one of which is invisible:
The home.html file is the site's homepage. Session_info.html is a page with a form containing any necessary session information, preferably simply a unique session identifier assigned when a user hits the homepage:
<HTML>
<HEAD>
<TITLE> Session Information for Internet Site
(Session_info.html)
</TITLE>
</HEAD>
<BODY>
<FORM NAME=Data>
<INPUT TYPE="HIDDEN" NAME="ID" VALUE="NULL">
</FORM>
</BODY>
</HTML>
After this very simple architecture has been established, the site has a relatively robust vehicle for state maintenance. Any time that information in the hidden frame must be retrieved or set, a simple JavaScript routine will do. No server-side manipulation need be done at all. For example, to set the Session ID value to "John Doe" from home.html, we need only do something like the following:
As long as the Session_info.html page is loaded into the invisible frame, this state information will be maintained and will be available to other pages within the site as they are loaded into and out of the MAIN frame. If implemented correctly, this may serve as an ideal solution to traditional state-management problems. However, the following concerns must be carefully handled:
Frame escape must be avoided. The user must not jump directly to a page which is meant to be viewed from within the frameset. This can be handled with JavaScript tests at the top of each page.
Sensitive information should be stored on the server and related to Session.Data.ID, in order to avoid potential information grabbing by other sites (Not an issue in IE 4.x).
Session unloading will occur if the invisible frame is ever loaded with another document. This must obviously be avoided.
This method is compatible down to the 3.x versions of Explorer and Navigator. I hope that my trials and tribulations prove helpful to other developers, and that I have not headed down a path with other unforeseen consequences.