reptile7's JavaScript blog
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 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.
Actually, 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:

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

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)