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.
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. |
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?
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:
name1Of course, your program will need to parse this string in order to extract the desired cookie information.=
value1;
name2=
value2;
name3=
value3;
...
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); }
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.
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:
To write a cookie: Enter a name and a value, then push the [write_cookie (name, value)] button. (If you don't want to use the default cookie path, enter a path also, then push the [write_cookie (name, value, path)] button instead.)
To read a cookie: Enter a name and push the [value = read_cookie (name, skips)] button. The value of the cookie, if found, will appear in the value field. (If there are multiple cookies with the same name, you may need to adjust the skips parameter.)
To delete a cookie: Enter the cookie's name and push the [delete_cookie (name)] button. (If the cookie you want to delete was not written to the default path, you must enter the cookie's path and push the [delete_cookie (name, path)] button instead.)
To delete all cookies: Push the [delete_all_cookies ()] button. (If you want to delete cookies that weren't written with the default cookie path, you must enter the correct path and push the [delete_all_cookies (path)] button instead.)
A simple experiment: To convince yourself that The Cookie Factory really does generate client-side persistent cookies, try the following experiment:
Here is a link you can use to download cookies.js, a file containing all of the cookie functions described in this article:
(1,320 bytes)
I welcome your feedback regarding these functions. Best of luck in your cookie ventures!
Charlton Rose
July 3, 1997