Saturday, July 28, 2007
JavaScript Cookies III
Blog Entry #83
First-time vs. return visitors
At the end of the previous post, we were discussing Script Tip #64's modified cookie script and the first if block of its putCookie( ) function:
cookie_name = "NameCookie2010"; var GuestName; var FirstTime;
function putCookie( ) {
if (document.cookie) {
index = document.cookie.indexOf(cookie_name);
FirstTime = "n"; }
In the "Place the Variable" section of Script Tip #64, Joe insinuates that if the document.cookie if condition returns true (
if a cookie exists) and if NameCookie2010 appears in the document.cookie return (
the index of the cookie was found,i.e., index is not equal to -1), then the user is a return visitor. True or false?
When I visit http://www.htmlgoodies.com/, the cookie below is placed on my hard disk:
RMID=04e708c346a3d1a0; domain=.htmlgoodies.com; path=/; expires=Friday, 31-Dec-2010 23:59:00 GMT
Because of its general domain=.htmlgoodies.com and path=/ settings, this cookie is associated with every page of the HTML Goodies site. Let's suppose that I surf to Script Tip #64 and test the Script Tips #60-64 Script's effect for the very first time via the "Try out the NEW Script" link; although this is my first visit to the Script Tip #64 Script demo page, document.cookie is not empty and converts to true vis-à-vis the if block above.
Pushing the envelope a bit, let's now suppose that http://www.htmlgoodies.com/ also writes to my hard disk the following cookie for keeping track of visitors to its "legacy" pages:
NameCookie2010=oldschool; domain=.htmlgoodies.com; path=/legacy; expires=Friday, 31-Dec-2010 23:59:00 GMT
For a first visit to the Script Tip #64 Script demo page/Script Tips #60-64 Script:
(a) document.cookie returns
NameCookie2010=oldschool; RMID=04e708c346a3d1a0*
and converts to true at the if (document.cookie) command line;
(b) document.cookie.indexOf(cookie_name) returns 0, which is assigned to index.
(*On my iMac, both MSIE and Netscape list cookies with a more specific path value prior to cookies with a less specific path value (domain values being equal) in the document.cookie string.)
For both of the preceding scenarios, "n" is assigned to FirstTime; in the former case, I will be greeted with putCookie's first prompt( ) box and will subsequently see Hello, (prompt( ) output), welcome back!!! on the page, whereas in the latter case, there won't be any prompt( ) dialog and I will see Hello, oldschool, welcome back!!! on the page, even though I am a first-time visitor in each case.
Cookies with the same name attribute value but different path attribute values are accepted individually by the browser - such cookies do not "override" one another - check out Example 2 at the end of the JavaScript 1.3 Client-Side Reference's "Netscape Cookies" Appendix.
OK, I admit it's unlikely that another HTML Goodies page would set a NameCookie2010 cookie. But here is my larger point: if you want to distinguish first-time and return visitors to a Web page via the Script Tip #64 Script or a related cookie script, then be sure that your tracking cookie has a sufficiently unique name attribute value.
The expires attribute value
Regarding a cookie's expires attribute value, Netscape's cookie property documentation says:
[A] valid cookie expiration date isActually, there are at least three other ways in which the above expires value format can differ from the return of the toGMTString( ) method of the Date object. On my computer when using MSIE, the toGMTString( ) return format is:
expires=Wednesday, 09-Nov-99 23:12:40 GMT
The cookie date format is the same as the date returned by toGMTString, with the following exceptions:
• Dashes are added between the day, month, and year.
• The year is a 2-digit value for cookies.
Tue, 9 Nov 1999 23:12:40 UTC
(November 9, 1999 was in fact a Tuesday.)
• The string begins with a three-letter abbreviation, and not the full name, of the day of the week.
• For the first nine days of a month, the string gives a 1-digit value for the day of the month.
• The string concludes with the UTC time zone designation.
Anyway, the question arises: if we attempt to set a cookie's expires value with the toGMTString( ) method -
var futureday = new Date("April 5, 2010");
var expiresday = futureday.toGMTString( );
document.cookie = "Cookie1Name=Cookie1Value; expires=" + expiresday;
- would that work, or would the browser throw an error? It'll work, say the folks at WebReference.com.
Netscape avers that
toGMTString( ) is no longer used and has been replaced by the toUTCString( ) method.Consistent with WebReference.com's earlier work, I find that the toUTCString( ) method can correspondingly be used to set a cookie expiration date with either MSIE or Netscape.
Extracting the value value, take 2
The Microsoft Developer Network's cookie property page provides an alternate, for-loop-based method for extracting the value attribute value of a cookie with a given name attribute value. MSDN's code is easily transplanted into the Script Tips #60-64 Script's getName( ) function:
function getName( ) {
// a two-character semicolon-space string separates each cookie in document.cookie
var aCookie = document.cookie.split("; ");
for (var i = 0; i < aCookie.length; i++) {
// a name/value pair is separated by an equal sign
var aCrumb = aCookie[i].split("=");
if (cookie_name == aCrumb[0])
return aCrumb[1]; } }
The function above uses the split( ) method of the String object to split
(a) document.cookie into its constituent cookies, and
(b) each document.cookie cookie into its name value and value value.
When the loop finds a match between cookie_name and aCrumb[0], then cookie_name's value value, which is held by aCrumb[1], is returned.
Alternate functions for the Script Tips #60-64 Script
Speaking of the getName( ) function, you've probably noticed that all of the getName( ) assignment statements also appear in the putCookie( ) function. I can see why the script's author set aside a separate function for determining the cookie_name value value, but given its redundant code, I myself would scrap getName( ) and remodularize the script according to the first-time-vs-return-visitor motif of the Script Tip #64 Script, as follows:
(1) First, let's retool the FirstTime conditional statements a bit and put them, along with the expires value, in the 'global' part of the first script element:
<script type="text/javascript">
var cookie_name = "myTotallyUniqueCookieName", FirstTime, GuestName;
if (document.cookie.indexOf(cookie_name) == -1) FirstTime = "y";
else FirstTime = "n";
var futureday = new Date("April 5, 2010");
var expiresday = futureday.toUTCString( );
(2) Next, let's replace the putCookie( ) function with newVisitor( ) and returnVisitor( ) functions:
function newVisitor( ) {
GuestName = window.prompt("Hello! What's your name?", "Nobody");
if (GuestName == null || GuestName == "") GuestName = "Nobody";
document.cookie = cookie_name + "=" + GuestName + "; expires=" + expiresday;
return GuestName; }
var index, namestart, nameend;
function returnVisitor( ) {
index = document.cookie.indexOf(cookie_name);
namestart = document.cookie.indexOf("=", index) + 1;
nameend = document.cookie.indexOf(";", index);
if (nameend == -1) nameend = document.cookie.length;
GuestName = document.cookie.substring(namestart, nameend);
if (GuestName == "Nobody") {
GuestName = window.prompt("Hello again!!!" + "\n"
+ "Last time you didn't tell me your name. Maybe you want to do it now?", "Nobody");
if (GuestName != "Nobody" && GuestName != null && GuestName != "")
document.cookie = cookie_name + "=" + GuestName + "; expires=" + expiresday;
else GuestName = "Nobody"; }
return GuestName; }
</script>
(3) Finally, the second script element can be recoded as:
<script type="text/javascript">
if (FirstTime == "y") document.write("Hello, " + newVisitor( ) + ", nice to meet you!!!");
else document.write("Hello, " + returnVisitor( ) + ", welcome back!!!");
</script>
Other HTML Goodies cookie tutorials
The Beyond HTML : JavaScript section of HTML Goodies features two cookie tutorials.
(1) "So, You Want To Set A Cookie, Huh?" offers a set-and-retrieve cookie script not that different from the Script Tips #60-63 Script; its demo may or may not work for you, as the URL paths to the demo page and to the tutorial main page are different.
(2) "So You Want A Cookie Counter, Huh?" offers a script (the tutorial's "Cookie Count Script" link is broken) that uses a cookie to count the number of times that a user has visited a Web page. In brief:
(a) The script sets a Counter_Cookie=1 cookie upon a first visit.
(b) Upon a second visit, the Counter_Cookie value value, 1, is extracted, converted from string to number via the eval( ) function, and incremented, and then a new Counter_Cookie=2 cookie is written, and so on for subsequent visits.
And that'll do it for our discussion of the Script Tips #60-64 cookie script(s) - good to the last crumb, eh? In the next entry, we'll wrap our tentacles around the Script Tips #65-68 Script, which displays colors corresponding to user-chosen color values.
reptile7
Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)