advertisement -- please support sponsors

cookies:
persistent cookies

Question:

How can I write a cookie in one page and then read that cookie in another? or alternatively pass data gathered in one page (not a remote!) and then access it in another?

-- Chris

JavaScript programs have access to the "magic cookie jar" through a special property of the document object called "cookie". This property acts like a String object in the sense that cookie strings can be read from it and written into it; however, the actual behavior of document . cookie is quite different from that of a normal string. In fact, how one uses document . cookie depends very much on whether one wants to read, write, or delete a cookie.

Because working with document . cookie is such a hassle, I have designed a suite of functions that you can use to insulate yourself from its complexities. I'll describe these functions in this article and show you how they can be used to read, write, and delete cookies. Afterwards, I'll present a special "laboratory" where you can experiment with these functions and learn more about the behavior of cookies. Finally, I'll provide a download link to a .zip file containing all of these functions.

writing a cookie

Note: It is assumed in this article that you already know what cookies are and are somewhat familiar with how they work. If you think you need to learn more about cookies before continuing, click the more info button.

You can create, update, or delete cookies by writing "set-cookie" strings to the document . cookie object, as shown below:
document . cookie = set_cookie_string .

The format for strings written to document . cookie is the same as the format for set-cookie headers sent by HTTP cookie servers, minus the "Set-cookie:" prefix.

If you don't understand the preceding paragraph, don't worry -- you don't need to. The write_cookie function, shown below, is designed to make cookie-writing easy. Although the versatility of write_cookie is somewhat limited, the omission of unnecessary features is exactly what makes it easy to use. It's good enough for most programmers' cookie needs.

Reminder: A download link for this and other cookie functions is given at the end of this article.
/******************************************************************************
function write_cookie (name, value);
function write_cookie (name, value, path);

write_cookie creates a cookie with the name, value, and path given in the
parameters.  If no path is supplied, write_cookie uses the document's default
cookie path.  Each cookie is set with an expiration time of 1 year.
******************************************************************************/

function write_cookie (name, value, path)
{
	// Build the expiration date string:
	var expiration_date = new Date ();
	expiration_date . setYear (expiration_date . getYear () + 1);
	expiration_date = expiration_date . toGMTString ();

	// Build the set-cookie string:
	var cookie_string = escape (name) + "=" + escape (value) +
		"; expires=" + expiration_date;
	if (path != null)
		cookie_string += "; path=" + path;

	// Create/update the cookie:
	document . cookie = cookie_string;
}

Setting cookies with write_cookie is really easy. The following code shows how to create a cookie that preserves the client's username, assuming it has already been stored in a variable called "username":

write_cookie ("username", username);

Pretty easy, don't you agree?

reading a cookie

The document . cookie object can be used to read cookies, too. When read, document . cookie returns a string containing a list of all cookies matching the current document's host and path. The format of this string is the same as the format for an HTTP request cookie header, minus the "Cookie:" prefix. In other words, reading document . cookie produces a string in the following format:

name1=value1; name2=value2; name3=value3; ...
Of course, your program will need to parse this string in order to extract the desired cookie information.

Again, if you are confused about preceding paragraph, don't worry. The following function, read_cookie (), is designed so that you can read cookies without knowing a lot about how they work:

/******************************************************************************
function read_cookie (key)
function read_cookie (key, skips)

read_cookie searches through the current document's cookie string (i.e., the
concatenation of all cookies readable by the current document) for a cookie
whose name is identical to key.  If read_cookie finds a matching cookie, it
returns a string containing the value of cookie.  If read_cookie cannot find a
match, it returns null instead.

An optional skips parameter may be supplied if there is a need to select among
multiple cookies with the same name.  If a skips parameter is supplied,
read_cookie will skip that many occurrences of matching cookies and then return
the next one it finds, or null if there aren't any more.
******************************************************************************/

function read_cookie (key, skips)
{
	// Set skips to 0 if parameter was omitted:
	if (skips == null)
		skips = 0;

	// Get cookie string and separate into individual cookie phrases:
	var cookie_string = "" + document . cookie;
	var cookie_array = cookie_string . split ("; ");

	// Scan for desired cookie:
	for (var i = 0; i < cookie_array . length; ++ i)
	{
		var single_cookie = cookie_array [i] . split ("=");
		if (single_cookie . length != 2)
			continue;
		var name  = unescape (single_cookie [0]);
		var value = unescape (single_cookie [1]);

		// Return cookie if found:
		if (key == name && skips -- == 0)
			return value;
	}

	// Cookie was not found:
	return null;
}

Remember the username cookie we created in the previous example? The following code shows how to read it:

username = read_cookie ("username");

Of course, if the username cookie was never set, then read_cookie ("username") will return null. Therefore, you should follow up with something like this:

if (username == null) { username = prompt ("Please enter your username."); if (username != null) write_cookie ("username", username); }

erasing a cookie

To erase a cookie, all you have to do is overwrite the same cookie with an expired cookie. The following code shows how to erase the username cookie we created in previous examples:

document . cookie = "username=any_value; " + "expires=Sat, 29 Jun 1996 01:44:48 GMT";

Admittedly, this is a lot of work just to delete a cookie. Let's make our lives easier by adding a delete_cookie function to our arsenal of cookie functions:

/******************************************************************************
delete_cookie (name)
delete_cookie (name, path)

delete_cookie deletes the cookie with the specified name and path.  If no path
is given, the default cookie path for the current document is used instead.  If
the name and path do not match an existing cookie, delete_cookie has no effect.
******************************************************************************/

function delete_cookie (name, path)
{
	// Build expiration date string:
	var expiration_date = new Date ();
	expiration_date . setYear (expiration_date . getYear () - 1);
	expiration_date = expiration_date . toGMTString ();

	// Build set-cookie string:
	var cookie_string = escape (name) + "=; expires=" + expiration_date;
	if (path != null)
		cookie_string += "; path=" + path;

	// Delete the cookie:
	document . cookie = cookie_string;
}

Now let's nuke the username cookie:

delete_cookie ("username");

I don't see how it could get any easier!

In case you decide to empty the cookie jar, here is another function, delete_all_cookies, which you can use to expire a handful of them at once:

/******************************************************************************
delete_all_cookies ()
delete_all_cookies (path)

delete_all_cookies deletes all cookies matching the specified path.  If no path
is supplied, the document's default cookie path is used.
******************************************************************************/

function delete_all_cookies (path)
{
	// Get cookie string and separate into individual cookie phrases:
	var cookie_string = "" + document . cookie;
	var cookie_array = cookie_string . split ("; ");

	// Try to delete each cookie:
	for (var i = 0; i < cookie_array . length; ++ i)
	{
		var single_cookie = cookie_array [i] . split ("=");
		if (single_cookie . length != 2)
			continue;
		var name = unescape (single_cookie [0]);
		delete_cookie (name, path);
	}
}

Note that delete_all_cookies employs delete_cookie to get much of its work done.

The Cookie Factory

In order to familiarize yourself with the behavior of cookies and the cookie functions presented in this article, you are invited to experiment in The Cookie Factory, a JavaScript-based cookie laboratory that uses the all of the cookie functions described in this article.

Instructions for The Cookie Factory are given below:

A simple experiment: To convince yourself that The Cookie Factory really does generate client-side persistent cookies, try the following experiment:

  1. Launch The Cookie Factory.
  2. Create a cookie of your choice.
  3. Close your browser and all of its windows.
  4. Launch your browser again.
  5. Load this page again.
  6. Launch The Cookie Factory again.
  7. Verify that the cookie is still there.

downloading the cookie functions

Here is a link you can use to download cookies.js, a file containing all of the cookie functions described in this article:

download cookies.zip (1,320 bytes)

I welcome your feedback regarding these functions. Best of luck in your cookie ventures!

Charlton Rose
July 3, 1997