This demonstration will give you a taste of how hard it can be to troubleshoot cookie overload and will also give Internet Explorer users - sorry I don't know how to do this for Netscape yet - a quick way to display the active cookies for the page currently displayed for just about any site. Along the way, you'll use an index loop, create variables using ColdFusion's evaluate function, and stuff javascript into a browser bookmark to make that javascript seem to be part of the current page.
This fragment opens a form and table, prepares to count cookies that are set, and opens a loop that will try to work with 30 cookies. The submit control is at the top of the form so you're less apt to be tempted by the length of the form to just press Enter without clicking on the submit control. This form is large enough that just pressing Enter may not be reliable.
<form name="stress" action="overload.cfm" method="post"> <table border="1"> <tr><td colspan="3"> <input type="submit" name="doit" value="Press TWICE"> </td></tr> <tr><td>Cookie is...</td><td>Form says...</td><td>Request...</td></tr> <cfset cookies="0"> <cfloop index="Num" from="1" to="30">
This fragment creates and works with a temporary variable whose name changes with each pass through the loop: form.val1, form.val2, form.val3, etc. When you first open the page, the form variables don't exist, and none of this code gets used. After you submit the page once, the form variables are defined. If (for example), form.val1 is defined, then the code checks for the existence of cookieval1. If cookieval1 is defined, then increment the cookie counter (previously set to zero) and display the word "SET". If cookieval1 is not defined, display a period. (I'd use a non-breaking space, but it's tedious to represent in a manner that you can copy.) If formval1 is the word "set", then write the number "1" to cookie.val1. If formval1 is the word "delete", then delete cookie.val1 by giving it a dummy value and an expiration date in the past. Allaire warns of dire consequences if you delete a cookie without giving it a value. Browsers usually interpret the value "-1" as a date in the past. Finally, form.val1 is changed to the word "ignore" so the form won't keep trying to change this cookie.
<cfset temp="form.val"&Num>
<cfif isDefined("#temp#")>
<td>
<cfif isDefined("cookie.val#Num#")>
<cfset cookies=cookies+1>
SET
<cfelse>
.
</cfif>
<cfif "#evaluate(temp)#" is "set">
<cfcookie name="val#Num#" value="#Num#">
</cfif>
<cfif "#evaluate(temp)#" is "delete">
<cfcookie name="val#Num#" value="ByeBye" expires="-1">
</cfif>
</td>
<td><cfoutput>#evaluate(temp)#</cfoutput></td>
<cfset "#temp#"="ignore">
The first time you submit the page, the form variables are not defined. This fragment puts periods where information would otherwise print.
<cfelse> <td>.</td><td>.</td> </cfif> <td>
This fragment shows the form controls, closes the loop and form, and shows how many cookies this page tried to set are currently set. It create a field on the fly for each pass: val1, val2, val3, etc. It does this by wrapping the controls in cfoutput tags so that the raw HTML will contain the new name and display the cookie number. The form starts out with a default of ignore for every cookie so that when the form is first displayed, pressing submit won't try to create or delete cookies unless the user changes some of the controls. Finally, after the table and form are closed, it displays the value of the cookie counter initialized and incremented by the preceding code.
<cfoutput> Set<input type="radio" name="val#Num#" value="set"> Ignore<input type="radio" name="val#Num#" value="ignore" checked> Delete<input type="radio" name="val#Num#" value="delete">: #Num# </cfoutput> </td> <tr> </cfloop> </table> </form> <cfoutput>#cookies#</cfoutput> cookies set by this page are currently set<br>
Using Internet Explorer, you can browse a page and then use a browser bookmark to apply javascript as if it were associated with the current page. The ability to do this adds to your arsenal of tools to work with Web sites. I wrote the javascript source from scratch for this tip, but the idea to use javascript in place of the URL in a bookmark comes from Steve Kangas at www.bookmarklets.com.
The code begins with a brief statement naming the language. It then opens a window. If the first parameter had contained a page name, the browser would have tried to load that page. Because it doesn't, it creates a new page, giving it the handle shown: w. (I named it this to think of "window".) The window also gets an arbitrary name (which won't be used): s. (I named it this to think of "show").
javascript:w=window.open('','s');
The browser returns all cookies associated with the current page. However, javascript thinks of these as a single cookie. If the cookie for the currrent document is empty, the code tells you that there are no cookies for this domain. I felt that being brief was more important than being completely correct in this instance. You're aware that cookies explicitly naming a different directory within this domain also won't show up. The intent of this tool is to tell you which cookies are being returned for the current document.
if(document.cookie==""){w.document.write("No cookies for this domain");}
This fragment breaks what javascript thinks of as a single cookie into its separate cookies by splitting it into chunks separated by semicolons. It assigns the result to a variable that I named c for "cookie". It then points to each cookie in turn and prints each one to a separate line. javascript counts from zero; so, this code sets a counter "i" to zero and increments it until all the cookies have been printed.
else{c=document.cookie.split(";");
for(i=0;i<c.length;i++){w.document.write(c[i]+'<br>');}
Finally, because once the window is open, this code will append to the window instead of opening a new one, it prints a couple of asterisks to separate "runs".
w.document.write('**<p>');}
Copy this code to Wordpad or something similar temporarily and remove the line breaks so it's all on one very long line in preparation for the next step.
Now send your browser to a URL that probably sets cookies. When the page has stopped loading, select this "favorite" as if you were going to a new Web site. The first time you do this, it will open a new window with "about:blank" in the URL. When I went to www.cftipsplus.com, the new window looked something like this:
CFID={your number}
CFTOKEN={your token}
**
Not much of a surprise there. Now as more sites use javascript, there's a chance that this javascript will conflict with the page to some extent. If you encounter an error, close the "about:blank" window, refresh the target page, and ask for the favorite again. You'll see some interesting stuff. Here's text similar to what I saw at a few popular sites. Note that many cookies appear to consist of multiple pieces of information, oddly joined.
Allaire...
CFID={your ID}
CFTOKEN={your token}
UID=61DEA9FE%2D9BBB%2D1D4%2DB2FC00508B94FD50 [a unique string]
Amazon.com...
session-id=104-9150644-4075955
session-id-time=994752000
ubid-main=077-5515814-8267138
x-main=hQFiIxHUFj8mCscT@Yb5Z8xsVsOFQjBf
obidos_path=continue-shopping-url=/subst/home/home.html/104-9150644-4075955
&continue-shopping-post-data=&continue-shopping-description=generic.gateway.default
seenpop=1
AOL...
Offer=nm_a
OfferExp=Fri%2C%206%20Jul%202001%2005%3A09%3A11%20UTC
Yahoo!...[yes, it looks broken]
B=6kcql7osneohe&b=2&f=s
Y=v=1&n=3jrn9luef86v6&p=
So now that you've demonstrated the impact of cookie overload and built a tool that can show you the active cookies for pages that you browse, extend these concepts. You've seen where browsers dump cookies based on number; see where popular browsers run out of space. Set cookies for specfic directories. Learn what cookies your browser is holding for your sites (and others). Understand, apply, and share what you learn. =Marty=
[Note: Firefox, not available when this demo was written, manages to hold onto all 30 cookies. However, Internet Explorer 6 and Netscape 8 still flunk this test.]