File Under: JavaScript, Programming

Advanced JavaScript Tutorial – Lesson 2

Welcome back. Now that your brain has re-acclimated to the semicolons and curly braces of the JavaScript world, it’s time to learn something useful and exciting.

We’ll spend this lesson sampling those tasty treats known as cookies – the little bits of information you can leave on the computers of people who visit your site. Cookies allow you to give your pages a personal touch. For instance, with a cookie you can “remember” people’s names and serve up a warm greeting every time they re-visit. You can also remember user preferences – if a visitor generally comes in on a slow connection, a cookie lets you know to automatically serve them minimal graphics.


Cookies can be very useful — and sometimes scary:When I buy airplane tickets online, the service I use remembers not only my name, but also where I live and my seating preferences. It even knows who I traveled with last and asks if that person will be joining me on my next flight. There’s a fine line between useful and invasive.

As long as you use them responsibly and effectively (and don’t freak anyone out with Big Brother knowledge), cookies can be extremely handy for all sorts of reasons. So I’m going to show you how they work. But before we get our hands all doughy, we should cover two JavaScript topics:fancy string handling and associative arrays.

Contents

  1. Fancy String Handling
  2. indexOf
  3. charAt
  4. String Exercise 1
    1. Substring
    2. The Split Method
    3. Associative Arrays
    4. Example of an Associative Array
    5. Cookie Introduction
    6. More About Cookies
  5. Setting Cookies
    1. Reading Cookies
  6. Complicated Cookie Reading
  7. Reading and Writing Multiple Cookies
  8. More About Cookies
  9. Cookie Path and Domain
  10. Lesson 2 Review

Fancy String Handling

Why do you have to learn about fancy string handling before getting into the joyous world of cookies? Well, it turns out that cookies are strings. To store visitor information, you have to first build a special cookie string. And then to read the information when the visitor returns, you have to decode the cookie string. To create and interpret these strings, you have to know your way around JavaScript’s string library.

You should be pretty familiar with strings, since we’ve been working with them all along, but for a refresher, take a look at Part I, Day 2 to see how to make an ordinary string bold:

 var normal_monkey = "I am a monkey!<br>";

 document.writeln("Normal monkey " + normal_monkey);

 var bold_monkey = normal_monkey.bold();

 document.writeln("Bold monkey " + bold_monkey);



The statement:

 var bold_monkey = normal_monkey.bold();

Is the same as the statement:

 var bold_monkey = "<b>" + normal_monkey + "</b>";

The first version just looks neater. One of the many methods of the string object is bold, and it’s sort of silly. Less silly are the methods indexOf, charAt, substring, and split, which actually get inside strings and see what they’re made of. Let’s look at indexOf first.

indexOf

The indexOf finds the location of a set of characters inside a string and tells you where the substring starts. If the string doesn’t contain the substring, indexOf returns “-1.” Here are some examples:

var the_word = "monkey";
Let’s start with the word “monkey.”
var location_of_m = the_word.indexOf("m");
The location_of_m will be “0,” because that’s the starting position of a string.
var location_of_o = the_word.indexOf("o");
The location_of_o will be “1.”
var location_of_key = the_word.indexOf("key");
location_of_key is “3″ because the substring “key” starts with “k,” which is position three in the word “monkey.”
var location_of_y = the_word.indexOf("y");
The location_of_y is “5.”
var cheeky = the_word.indexOf("q");
The cheeky is “-1″ because there’s no letter “q” in the word “monkey.”

A more realistic use of indexOf is:

 var the_email = prompt("What's your email address?", "");

 var the_at_is_at = the_email.indexOf("@");

 if (the_at_is_at == -1)

 {

 	alert("You loser, email addresses must

 	have @ signs in them.");

 }

This little scrap of code asks users for their email address, and then checks to see if it’s a valid address. If the address doesn’t contain an @ sign, it can’t be valid. Enter indexOf, which checks for “@” in the string.

charAt

The charAt finds out what letter is at a certain position inside a string. Here it is in action:

 var the_word = "monkey";

 var the_first_letter = the_word.charAt(0);

 var the_second_letter = the_word.charAt(1);

 var the_last_letter = the_word.charAt(the_word.length-1);



After this, the_first_letter is “m,” the_second_letter is “o,” and the_last_letter is “y.” Note that you can find out how many letters are in a word using the length property of the string. In this case, the_word is “monkey,” so the_word.length is “6.” Don’t forget that the first character of a string is at position “0″ (as in charAt(0)), so the last letter will be in position length-1, which is why the last line features the_word.length-1.

Before going over substring and split, let’s do an exercise with charAt and indexOf.

String Exercise 1

Your task is to write a script that will determine whether the last letter of a word is a vowel or a consonant. You can do it in a clever way, using both indexOf and charAt. Of course you could do it in a much less clever way without indexOf, but remember:the clever monkey gets the golden banana.

Here’s an example of it working. When you’ve finished the exercise, or nearly died trying, learn how it’s done or double-check your work against my solution. Or, if you’re so pleased with your solution that you don’t want to sully your mind with mine, feel free to carry on with the string-a-thon.

Substring

The substring is just like charAt except it can grab entire substrings from a word, not just letters. Here’s the format:

 var the_substring = the_string.substring(from, to);

“From” refers to the position of the first character of the substring, and “to” is, strangely enough, one greater than the last position of the substring. Using this weird method to mark the beginning and end of the substring makes it so that “to” minus “from” gives you the length of the substring:

 var the_string = "monkey";

 var clergy = the_string.substring(0,4);

 var tool = the_string.substring(3,6);

After this batch of code runs, “clergy” will equal “monk”; “tool” will equal “key.”

The substring is often used with indexOf to break apart strings. For example, you could pull out the domain name of a given URL:

 var the_url = prompt("What's the URL?","");

 var lead_slashes = the_url.indexOf("//");

 var domain_start = lead_slashes + 2;

 var without_resource = the_url.substring(domain_start, the_url.length);

 var next_slash = without_resource.indexOf("/");

 var domain = without_resource.substring(0, next_slash);

Which means if you enter “http://www.webmonkey.com/javascript/index.html,” the domain will equal “www.webmonkey.com.” Try the domain grabber to see it work. If this code seems like kind of a drag to you, don’t worry. After I break it down line by line, I’ll show you how to make things much simpler using the split method. First, however, the analysis.

The basic tactic we’re using here is to isolate everything between the first double slash and the next slash. Here’s how we do it:

var the_url = prompt("What's the URL?","");
This just asks the user for a URL. Let’s say they enter “http://www.webmonkey.com/javascript/index.html.”
var lead_slashes = the_url.indexOf("//");
This locates the first two slashes. In the case of our example URL, lead_slashes equals “5″ because the two slashes start at position five. What’s that? You wonder, “if the string is a URL, it always starts with http://, so why don’t we just assume, oh so cleverly, that the two slashes start at position five instead of messing around with indexOf?” The thing is, you never know what people will do at the prompt. They might enter “the URL I want is http://www.blah.com/.” Or they might accidentally put a space before the URL. Or maybe they enter a URL that’s on a secure server, making it something like “https://www.whatever.com/.”One of the hardest things about programming is anticipating all possible cases and then coming up with a way to handle them. Ask people to drop information into an open text field, and you never quite know what you’ll get. So we can’t just assume that the two slashes are at positions five and six. Instead, we need to use the indexOf method to determine exactly where the two slashes start.
var domain_start = lead_slashes + 2;
This calculates the location of the first letter of the domain. Because there are two slashes, the first letter of the domain will be two positions over from the slashes.
var without_resource = the_url.substring(domain_start, the_string.length);
This grabs everything from the beginning of the domain name (which we determined in the previous line of code) and the end of the string. So, using the current example, without_resource is “www.webmonkey.com/javascript/index.html.”
var next_slash = without_resource.indexOf("/");
This figures out the position of the next slash in the string. Everything between the beginning of the string and this slash is domain name. In this case, the next slash is in position seventeen.
var domain = without_resource.substring(0, next_slash);
This final step grabs everything from the beginning of the string to the position of the next slash. In the current case, that makes domain equal to “www.webmonkey.com.”

And there you have it. Yes, it’s a pain. If it makes you feel any better, string handling is a pain in almost all languages. JavaScript 1.2, which was introduced with Netscape 4.0, takes some strides toward making string handling easier. But it’s still a pain.

The whole process can be handled quite a bit more easily with the split method.

The Split Method

When you have a list of things separated by a delimiter, you generally use split. Say you have a list of names separated by commas – split takes that list and puts each of the names into an array. For example:

 var my_friends = "trixie,moxie,sven,guido,hermes";

 var friend_array = my_friends.split(",");

 for (var loop=0; loop < friend_array.length; loop++)

 {

     document.writeln(friend_array[loop] + " is my friend.<br>");

 }

This breaks the string my_friends into an array of five elements. (Happily, JavaScript creates the array for you automatically, so you don’t have to use new Array() to create it yourself).

After breaking the string into an array, we loop through it, writing out each friend’s name. If arrays or loops are unfamiliar to you, check out Part I, Day 4 for an explanation.

We can use split to make the earlier domain grabber easier to code:

 var the_url = prompt("What's the URL?","");

 var first_split = the_url.split("//");

 var without_resource = first_split[1];

 var second_split = without_resource.split("/");

 var domain = second_split[0];

This is much more attractive, and easier to understand, right? Here’s the breakdown:

var the_url = prompt("What's the URL?","");
As before, this requests a URL (let’s go with “http://www.webmonkey.com/javascript/index.html” again).
var first_split = the_url.split("//");
This splits the string into two pieces:first_split[0] is “http:” and first_split[1] is “www.webmonkey.com/javascript/index.html.”
var without_resource = first_split[1];
This just grabs the second element in the array, so now without_resource is “www.webmonkey.com/javascript/index.html.”
var second_split = without_resource.split("/");
This breaks without_resource into three pieces:www.webmonkey.com, javascript, and index.html. See how useful split is?
var domain = second_split[0];
Now all we have to do is grab the first element of the second_split array. And voila! We’re done.

That might seem to be a lot of work at first, but you’ll get used to it pretty fast. I personally love split – it’s a special coding treat.

Now that you’ve learned all the fancy string handling routines for cookies, take a breather – you’ve just digested quite a mouthful of information. Go for a little stroll. Have a snack. OK? Then it’s time to learn one last thing before sallying forth into cookie country:associative arrays.

Associative Arrays

If you’ve done any JavaScript programming, you’re probably familiar with arrays, which let you store lists of items and also give you access to the images, forms, and form elements of your HTML pages. In Part I, Day 4, I showed you how to create and manipulate arrays that are indexed by number. For example:

 var an_array = new Array("hickory","dickory");

 var element_one = an_array[0];

 var element_two = an_array[1];

 an_array[2] = "doc";

This creates a new array and initializes it with two strings. The first element of the array is accessed using its index number, “0.” The second element, element 1 of the array, is accessible with an_array[1]. You can add to an array by assigning something to a specific index of the array:in the example above, I made the third element of the array equal to “doc.” Now the array contains “hickory, dickory, doc.”

Associative arrays are just like the array above, except rather than using numbers to index elements in the array, you use words.

 var phone_book = new Array();

 phone_book["sleepy"] = "(203) 555-1234";

 phone_book["happy"] = "(203) 555-2345";

This creates sort of a phone book. Access the phone number for “happy” by writing:

 var happy_number = phone_book["happy"];

Try out the working phone book example on the next page to see how an associative array might work (and get a major refresher on the use of JavaScript with forms at the same time).

Example of an Associative Array

Click here.

This example is a bit involved, so let’s go through it slowly. First let’s look at the phone book itself. The phone book, which is defined in the header ( phone_book) and has seven entries, looks like this:

 var phone_book = new Array();

 phone_book["happy"] = "(203) 555-1234";

 phone_book["sleepy"] = "(203) 555-2345";

 phone_book["sneezy"] = "(203) 555-4321";

 phone_book["sleazy"] = "(203) 555-3245";

 phone_book["sneery"] = "(203) 555-3213";

 phone_book["bleary"] = "(203) 555-2365";

 phone_book["tweaked"] = "(203) 555-1664";

The key to each entry is the name of the dwarf, and the value of each entry is that dwarfs’s phone number. When we want to get a phone number for our favorite dwarf, say “Sneezy,” we write this:

 var the_number = phone_book["sneezy"];

Now let’s look at the form:

 <form name="the_form">



 <b>Name:</b>

 <select onChange =

 "displayNumber(phone_book,this.options[selectedIndex].value);">

 <option value="happy">Happy

 <option value="sleepy">Sleepy

 <option value="sneezy">Sneezy

 <option value="sleazy">Sleazy

 <option value="sneary">Sneery

 <option value="bleary">Bleary

 <option value="tweaked">Tweaked

 </select>



 <p>

 <b>Number</b>

 <input type="text" name="number_box" value="">

 </form>

Note that the form and the elements inside the form have names. This allows us to read and write to the form elements. Also, take a look at the onChange handler in the select tag. This says that when the select is changed, it calls the function displayNumber, which is defined up in the header. If I use the pulldown to select “sneezy,” the expression this.options[selectedIndex].value returns “sneezy.” If you need a refresher on this kind of form madness, check out Part I, Day 5. Once we’ve figured out what the user has selected, we jump to the displayNumber function, which looks like this:

 function displayNumber(phone_book, entry)

 {

     var the_number = phone_book[entry];

     window.document.the_form.number_box.value = the_number;

 }

It takes two parameters – a phone book and a name – to make this function work. The first line of the function,

 var the_number = phone_book[entry];

looks the name up in the phone book, and the next line,

 window.document.the_form.number_box.value = the_number;

puts that number into the form element called number_box.

And there you have it. As you can see, associative arrays are a good way to link one string to another. They’re useful for linking names to phone numbers, to passwords, to birthdays, and all kinds of things. A few lessons from now, I’ll introduce another useful trick you can do with associative arrays, so don’t cast them into the facts-best-forgotten pit quite yet.

And now, if you’re ready for it, let’s sink our teeth into cookies!

Cookie Introduction

Now that you’ve mastered advanced string handling and associative arrays, it’s time to open up the cookie jar. As I mentioned earlier, cookies are little bits of information that you can leave on a user’s hard drive, where they stay even after the user leaves your site or turns off the computer, which is extremely useful when you want to remember information about repeat visitors.

Let’s look at a basic example of a working cookie. In this example, we set a cookie on one page and then read it from another page. As you play around with the example, try to think about how you would do this without cookies. Here’s the very basic example of a working cookie.

Had your fill of cookie dough tasting? Let’s move on to the next step of the recipe.

More About Cookies

Because cookies involve writing to, and reading from, users’ hard drives, security issues arise that the people who wrote Netscape, MSIE, and the other cookie-friendly browsers had to confront. The most important limitations for this tutorial are:

  1. Not everyone has a cookie-friendly browser (but most do).
  2. Not everyone who has a cookie-friendly browser will accept your cookies (but most will).
  3. Each domain is allotted only 20 cookies, so use them sparingly.
  4. Cookies must be no larger than 4 KB. That’s just over 4,000 characters, which is plenty.

With those limitations in mind, let’s learn about setting cookies.

Setting Cookies

Setting a basic cookie is very easy. All you have to do is create a string in the form of cookie_name=value and then set the document.cookie property to that. The only trick:cookie values must never have spaces, commas, or semicolons. Happily, you don’t really have to worry about this because a pair of functions will code and decode your properties:they are escape() and unescape().

Our simple example, which stored your name as a cookie, looks like this:

function setCookie()

{

    var the_name = prompt("What's your name?","");



    var the_cookie = "wm_javascript=" + escape("username:" + the_name);



    document.cookie = the_cookie;



    alert("Thanks, now go to the next page.");



}

The middle two lines of this function are the critical ones:

var the_cookie = "wm_javascript=" + escape("username:" + the_name);
If I entered “dave thau” at the prompt, this line would create a string that looks like wm_javascript=username%3Adave%20thau. This means that I’m going to save a cookie named wm_javascript to the hard drive. That cookie is going to have the value username%3Adave%20thau – the escape() function replaced the colon after username with %3A and the space between “dave” and “thau” with a %20.When we read the cookie, we’re going to look for the cookie named wm_javascript, then grab the username%3Adave%20thau, unescape() it, which changes the %3A back to a colon and the %20 back into a space, and then chop off the username:.
document.cookie = the_cookie;
And this sets the cookie. Easy, huh?

Now let’s learn how to read cookies.

Reading Cookies

Once you save a cookie to someone’s hard disk, it’s easy to read. Here’s the code that reads the example cookie:

function readCookie()

{

    var the_cookie = document.cookie;

    var the_cookie = unescape(the_cookie);

    var broken_cookie = the_cookie.split(":");

    var the_name = broken_cookie[1];

    alert("Your name is:" + the_name);

}

The first line is the important one. Whenever your browser opens a Web page, it calls in whatever cookies it can, then loads them into the document.cookie property.

The tricky part about reading cookies is getting the information you want out of them. Remember, the cookie we set looks like this:wm_javascript=username%3Adave%20thau. Everything after the first line of the function is devoted to pulling the username out of the cookie. Here’s a breakdown of that process:

var the_cookie = unescape(the_cookie);
Undo the stuff that the escape() function created. In this case, unescape() swaps the %3A with a colon, and the %20 with a space.
var broken_cookie = the_cookie.split(":");
Split the cookie into two parts at the colon.
var the_name = broken_cookie[1];
Grab the part after the colon, which is dave thau.
alert("Your name is:" + the_name);
Yee-haw!

This example used a cookie that only stored one bit of information:the username. As I said before, cookies can store up to 4 KB, which leaves plenty of room for quite a bit more information.

Complicated Cookie Reading

If you want your cookie to contain more than just one piece of information, you can make the value of the cookie as long as you want (up to the 4000 character limit). Say you’re looking to store a person’s name, age, and phone number. You do something like this:

var the_cookie = "username:thau/age:older than the hills/phone:411";

document.cookie="my_happy_cookie=" + escape(the_cookie);

I use a slash to separate property names and a colon to distinguish the property name from the property value. The slash and colon are arbitrary choices – they could be anything, like say, this:

var the_cookie = "username=thau&age=older than the hills&phone=411";

document.cookie="my_happy_cookie=" + escape(the_cookie);


The delimiters you choose are up to you. Just remember what you used so you can decode the cookie later.


As with our simple example, the easy part is setting the cookie. Things get a little sticky, however, when it comes to pulling the information out of the cookie when you need it. I suggest using associative arrays to store all the information. For example, let’s say you saved this to someone’s hard drive:

my_happy_cookie=username:thau/age:older than the hills/phone:411

You could put the information into a handy associative array like this:

function readTheCookie(the_info)

{

// load the cookie into a variable and unescape it



var the_cookie = document.cookie;

var the_cookie = unescape(the_cookie);



// separate the values from the cookie name



var broken_cookie = the_cookie.split("=");

var the_values = broken_cookie[1];



// break each name:value pair into an array



var separated_values = the_values.split("/");



// loop through the list of name:values and load

// up the associate array



var property_value = "";



for (var loop = 0; loop < separated_values.length; loop++)



{

property_value = separated_values[loop];

var broken_info = property_value.split(":");

var the_property = broken_info[0];

var the_value = broken_info[1];

the_info[the_property] = the_value;

}



}

If you had this function in your JavaScript, you could call it like this:

var cookie_information = new Array();

readTheCookie(cookie_information);

And then you’d have cookie_information["username"], cookie_information["age"], and cookie_information["phone"] set correctly.


This may look a little funky, but actually it’s not that hard. Here’s a step-by-step analysis of what’s going on:


var the_cookie = document.cookie;
This is the easy part. It puts the cookie into a variable.
var the_cookie = unescape(the_cookie);
Undo the work of escape().
var broken_cookie = the_cookie.split("=");
var the_values = broken_cookie[1];
These lines make the_values equal to username:thau/age:older than the hills/phone:411.
var separated_values = the_values.split("/");
This makes an array called separated_values that contains three elements:separated_values[0] = "username:thau"
separated_values[1] = "age:older than the hills"
separated_values[2] = "phone:411"
for (loop = 0; loop < separated_values.length; loop++)
This loops through the three elements of separated_values.
property_value = separated_values[loop];
This grabs the current name:value pair, the first one being username:thau.
var broken_info = property_value.split(":");
This breaks the pair into two elements into an array called broken_info where broken_info[0] = "username"
broken_info[1] = "thau"
var the_property = broken_info[0];
The first time through the loop, the_property will be “username”
var the_value = broken_info[1];
the_value will be “thau.”
the_info[the_property] = the_value;
Here’s where associative arrays come in handy. This makes the_info["username"] = "thau". So now, when you want the username from the cookie, you can just say something like var the_name = the_info["username"];.
And so on
Each time through the loop, a new element gets added to the_info. At the end of the loop is the_info["username"] = "thau", the_info["age"] = "old as the hills" and the_info["phone"] = 411.

It is a bit cumbersome, but it’s the way I prefer to get large quantities of information in and out of cookies. There are lots of ways to do it, and if you find another way that you like, all the power to you.

Okay, the last thing you need to know is what to do when you’re dishing out multiple cookies.


Reading and Writing Multiple Cookies

On the last page, we learned how to cram lots of information into one cookie. Another way to do this is with multiple cookies.

Saving multiple cookies is very straightforward. We’ve learned that every cookie has a name. In the last example, we named the cookie my_happy_cookie, and did something like this:

var the_cookie = "my_happy_cookie=happiness_and_joy";

document.cookie = the_cookie;



To save multiple cookies, just give each cookie a different name. If you’re adding a new cookie, setting document.cookie doesn’t delete cookies that are already there. So if we do this:

var the_cookie = "my_happy_cookie=happiness_and_joy";

document.cookie = the_cookie;

var another_cookie= "my_other_cookie=more_joy_more_happiness";

document.cookie = another_cookie;

You’ll now have access to both cookies. It’s sort of weird, so make sure you understand what’s going on.

Let’s assume you executed the last block of code and you want to access my_happy_cookie. If you look at document.cookie, you’ll see this:

my_happy_cookie=happiness_and_joy;

my_other_cookie=more_joy_more_happiness;

If you don’t believe me, just look at your cookie.

This is very nice, but it makes reading a specific cookie a bit more difficult. Here’s some (slightly simplified) code that allows you to isolate a specific cookie:

function WM_readCookie(name) {

if (document.cookie == '') {



// there's no cookie, so go no further



return false;

} else {



// there is a cookie



var firstChar, lastChar;

var theBigCookie = document.cookie;

firstChar = theBigCookie.indexOf(name);



// find the start of 'name'



if(firstChar != -1) {



// if you found the cookie



firstChar += name.length + 1;



// skip 'name' and '='



lastChar = theBigCookie.indexOf(';', firstChar);



// Find the end of the value string (i.e. the next ';').



if(lastChar == -1) lastChar = theBigCookie.length;



return unescape(theBigCookie.substring(firstChar, lastChar));



} else {



// If there was no cookie of that name, return false.



return false;

}



}



}



// WM_readCookie

Since this is very well commented, I’ll just let you take a look at it and figure out what’s happening on your own (c’mon, you know everything you need to know to make sense of this).

Once you’ve parsed that information, let’s leave our “setting and reading basic cookies” discussion and look at some of the cooler things you can do with cookies.

More About Cookies

So far, you’ve learned how to set and read a basic cookie. Unfortunately, your basic cookie will get deleted automatically when a user quits out of the browser. Sometimes this is for the best. Since each domain, such as webmonkey.com, is allowed only 20 cookies on any user’s machine, you don’t want to waste space with cookies that aren’t saved between browser sessions.

However, if you do want to save cookies on users’ hard drives, you have to set an expiration date, which has to be in a special format called GMT. For example:

Mon, 27-Apr-1998 00:00:00 GMT

(This is the date on which Koko the gorilla had her AOL chat session.)

Getting the GMT right can be sort of a pain, especially when it comes to figuring out the day of the date. Is it a Monday? A Friday? To make things easier on you, JavaScript has a date method called toGMTString. Here’s an easy way to set an expiration date to some distant time in the future:

var the_date = new Date("December 31, 2023");

var the_cookie_date = the_date.toGMTString();

Once you establish an expiration date for your cookie, you have to add this information before you set the cookie. Therefore, your cookie should look like this:

cookie_name=blah_blah;expires=date

Basically, you’re just adding expires=date to the cookie string and separating the different cookie components with a semicolon.

Here’s how to build a cookie that will last until the end of the Mayan calendar:

function setCookie()

{



// get the information



//



var the_name = prompt("What's your name?","");

var the_date = new Date("December 31, 2023");

var the_cookie_date = the_date.toGMTString();





// build and save the cookie



//



var the_cookie = "my_cookie=" + escape(the_name);

the_cookie = the_cookie + ";expires=" + the_cookie_date;

document.cookie = the_cookie;



}

At the end of all this, the_cookie will look something like this:

my_cookie=thau;expires=Fri, 31-Dec-2023 00:00:00 GMT

When this cookie is set, it will live on the user’s hard drive until the expiration date.

The expiration date also allows you to delete cookies you don’t want users to have any more. If you set the expiration date of a cookie to a time that’s already passed, the cookie will be deleted from the cookie file.

In addition to name and expires, there are two other important cookies components that you’ll need to know about: path and domain.

Cookie Path and Domain

This is the last tricky cookies hurdle: By default, a cookie can be read only by HTML pages that sit on the same web server and in the same directory as the page that set the cookie.

For example, if you have a JavaScript on “http://chimp.webmonkey.com/food/bananas/banana_puree.htm” that asks people for their names, you might want to access a given name on another one of your Web pages, such as the homepage (http://chimp.webmonkey.com/.) To allow this, you have to set the “path” of the cookie. The “path” sets the top level directory from which a cookie can be read. Set the path of a cookie to the top-level directory of your Web pages, and the cookie is readable by all your Web pages.

Do this by adding path=/; to your cookie. If you just wanted the cookie readable solely in the “food” directory, you’d add path=/food; to your cookie.

A second hitch is that some Web sites have lots of little domains. For example, Webmonkey might have pages at “chimp.webmonkey.com,” “gorilla.webmonkey.com,” and “ape.webmonkey.com.” By default, if a Web page on “chimp.webmonkey.com” sets a cookie, only pages on “chimp.webmonkey.com” can read it. If we wanted all the machines in the “webmonkey.com” domain to read the cookie, we’d have to add “domain=webmonkey.com” to the cookie. Don’t get clever though. Pages at “republicans.com” can’t set or read cookies from “democrats.com.”

To put all the above together – set a cookie on the Web page “http://chimp.webmonkey.com/food/bananas/banana_puree.htm” that we want to be readable by all Webmonkey pages – we’d have to do this:

function setCookie()

{

var the_name = prompt("What's your name?","");

var the_cookie = "cookie_puss=" + escape(the_name) + ";" ;

var the_cookie = the_cookie + "path=/;";

var the_cookie = the_cookie + "domain=webmonkey.com;";

document.cookie = the_cookie;

}

And so ends the cookies lesson. Let’s review what we’ve learned so far and then go onto a final exercise.

Lesson 2 Review

Today was a big day, probably the biggest in this set of lessons. However, the things you learned today take you a significant step closer to the ability to create JavaScripts that are more than just cute. For example, today’s homework assignment is to add a “bookmarks” feature to your do-it-yourself Web browser.

Here are the main topics we covered today:

Advanced String Handling
Including
  • charAt – getting a character at a certain position
  • indexOf – getting the position of a character
  • substring – getting a piece of a string
  • split – splitting a string up into an array
Associative Arrays
Another JavaScript datatype useful for storing things like phone books, password lists, birthdays, and cookie information
Cookies
How to set them, read them, and make them permanent

Tomorrow we’ll cover:

  • Preloading images to speed up image swaps
  • Creating your own objects and a do-it-yourself virtual pet
  • Getting to hard-to-find objects


Before closing the JavaScript book entirely for the day, you can hone your knowledge by trying this homework assignment.

OK, ready? Next!