News Outline Schedule Tutorials Project Tools Links

Tutorials: Cookies with JavaScript

What are Cookies?

The short answer is that cookies are a way of saving data in a web page that will last even after the viewer has moved to another page. This information is stored in the web browser, in such a way that your scripts will be able to read and write to it afterwards. It's like storing things to a local file on the user's computer, but only in a limited way, to prevent malicious web page designers from harming your computer. Because variables in Javascript cease to exist once you leave the page they are created on, Cookies provide you with a way to pass information from one page to another, as well as the ability to save information to determine whether or not a user has visited your site before, and information about what their preferences for viewing your site may be.

Cookies can be used by both Client Side scripting (JavaScript) and Server Side scripting (such as PHP). In both situations, the cookie is a piece of information which is stored by the web browser, locally on the viewer's computer - once the viewer has moved on to a different web site, the server no longer has access to the cookie, and JavaScript scripts run in the browser are also cut off from it. Regardless of whether it was set by a Server Side script, or a Client Side script, your cookie will only be accessible while viewing the website where it was created. (Thus, you can not use a cookie to pass information from your website on electron.cs.uwindsor.ca to another site on geocities.com.)

What can you put into a Cookie?

Cookies are designed to hold information as strings, so you can put any information that you are able to convert into a string into your cookie, with one exception. The value of your cookie can not contain the ';' character - the reason for this will be explained a bit more in the section about actually creating cookies, as well as the best way around the problem.

You can store up to 20 cookies for any individual web site. The combination of the domain in the URL (ie: electron.cs.uwindsor.ca), and the path in the URL (ie: /60-270/03W/userid/) is used to decide what can be considered as a single web site. Thus, your project can store up to 20 cookies, and the cookie set by the other projects in the class will not be counted against you, because they have a different path, and if you made a copy of your website on SOCR's web server, those cookies would also be stored separately due to having a different domain.

Inside of each cookie, you are allowed 4 KB of space. This means 4096 letters per cookie, which are divided up between the name of your cookie, the value of your cookie, and two special characters that separate the cookie from others that are being stored. Since you have 20 Cookies, and around 4Kb for each of them, this means that your website can store up to 80Kb of data - more than enough space to store a good sized essay in. (The largest file used in the class website is only 32Kb.)

How do I use a Cookie?

There are two ways to access a Cookie - from the server side, or a client side script - since this section of the class is about Client Side scripting, we will only be discussing how to access a cookie from inside JavaScript here. The Cookie itself is stored through the Document Object Model in a property called document.cookie - this special property holds all of the cookies assigned to your web site, with their names, and semi-colons between them. Thus, if you had three cookies, "c01","c02", and "that", and they each contained the word "boo", document.cookie would contain the following:

c01=boo; c02=boo; that=boo

In each case, the cookie starts with it's name, which ends at the '=', and then the cookie's value begins, and ends at a ';' - thus, you can not put '=' in the name of your cookie, and you can not put ';' in it's value.

When you want to actually set a cookie however, you do not set all of the cookies at once - instead, you should set them one at a time, like this:

document.cookie="big=waaah"; document.cookie="small=wheee"; document.cookie="another=one";

After running this set of statements, the contents of document.cookie will be changed to this:

c01=boo; c02=boo; that=boo; big=waaah; small=wheee; another=one

The reason this works is because document.cookie is a special property which takes the values placed into it in a different manner than the data that is output. In each of these cases, we were creating new cookies, but you can also change the value in an old cookie, just by setting it again with the same name, but a different value, like this:

document.cookie="another=three";

The altered document.cookie will now contain:

c01=boo; c02=boo; that=boo; big=waaah; small=wheee; another=three

Since the ; character (and also the newline character) is not allowed in the value of a cookie, you must find some way around this problem - the solution is provided as a pair of builtin functions in JavaScript, called escape(), and unescape(). When you submit a form via the form tag, the data which is passed along is encoded so that all special characters are converted into a % and a hexidecimal number representing the ascii value of that character. The escape() function does the exact same thing, and unescape() will convert information back. If you run escape() on your cookie value before saving it, and unescape() on it when you read it back in, you'll have no problems with accidental illegal characters crashing your scripts.

var theText = "This is a line; it has lots of stuff on it."; theText = escape(theText); document.cookie="newcook="+theText;

The above will make document.cookie contain this:

newcook=This%20is%20a%20line%3B%20it%20has%20lots%20of%20stuff%20on%20it.

Note that the spaces were all converted to %20 (20 is the Hex code for the space character in ascii), and the ; was converted to %3B. The only difficulty with this method is that it will result in your cookie becoming much longer if it contains a lot of space characters, since each one is converted into three characters instead of just one. Fortunately, you still have 4K to use, so most cookie values will not be affected by this.

Expiration Dates:

In the above examples, the only parts of the cookie that were set were the name and value - they are the only parts of a cookie which are absolutely required, but there are additional things about cookies which can also be set.

The cookies set above will exist only until the browser shuts down - if someone closes the program itself, and starts it up again, they will not be there anymore. The reason for this is because they were set only with their name and value - to make a cookie last past the next time you shut down the browser, you must also set what is called an expiry property on it, to tell the browser how long to keep the cookie. (This is much like the expiry date on a carton of milk - once it has gone by, the browser throws the cookie out.) To set an expiry date of November 15th, 2005 at 10:11 pm, you would use this command:

document.cookie="name=value; expires=Sat Nov 15 22:11:00 EDT 2005"

Reading back the contents of document.cookie will not include the expiry date however, as the browser considers the cookie's expiry date private, and will not share it with your script.

Obviously, this method is not optimal if you wish to make your cookie's expiration date dynamic, (ie: expire one year from the time it is set,) mainly because of the complexity of formatting the date string, and deciding which day of the week you should put it on. Fortunately, JavaScript provides an easy way around that - the Date object. To create a properly formated string with the date for one year from now, you merely need to create a Date object in JavaScript, set the date/time to the one you want, and convert it back into a string. In the following example, we do this to set the date to exactly one year from the current date:

var expDays = 365; var exp = new Date(); exp.setTime(exp.getTime() + (expDays*24*60*60*1000)); document.cookie="name=newvalue; expires=" + exp;

The cookie stored with the name "name" will now last for exactly one year from the time when it was set. By the same method, we can force the browser to delete a cookie right now for us, by setting the cookie again, with an expiration date that is in the past:

document.cookie="name=whatever; expires=Thu Feb 10 15:27:37 EST 2000";

The new 'old' expiry date will result in the browser throwing out the cookie.

Sharing your Cookie - PATH and DOMAIN:

Earlier, it was mentioned that your cookie would only be visible to web pages with the same domain and path as the page which created it, however it is possible to get around this limitation to some extent. When creating your cookie, much like the expiry property, you can also set a domain and/or path property, which can be used to share your cookie across other web sites. Remember when you do this however, that it is then very important to name your cookie something unique, as if some other website uses the same name as your cookie, there will be a chance of your data (or theirs) being lost, and harming the way your website works.

First, it is important to understand what the path and domain of a URL are. In the URL http://electron.cs.uwindsor.ca/60-270/03W/userid/myFile.html, the domain would be electron.cs.uwindsor.ca, and the path would be /60-270/03W/userid/. The domain is the name of the machine the web page is located on, and the path is the list of directory names in the URL. (Remember that the path does not include the filename, however.) Any time you create a cookie, and do not specify a path or a domain, they will default to the most specific possible value, which means the whole thing gets used, and only web pages with a domain and path which contains the entire domain and path on the cookie will be allowed to see the cookie.

Using the PATH property:

To share your cookie with pages in other directories on the machine it is on, you must force the path of the cookie to be less specific than it started out. If you set your path to just /60-270/03W/, instead of /60-270/03W/userid/, then all of the other projects in the class would also have access to it, and setting it to / would allow access to your cookie from all HTML files on the server electron.cs.uwindsor.ca. In small websites, this is rarely necesary, but as websites get larger, sometimes it is necesary to split your files up into separate directories, depending on what the content of those files may be. In those cases, if your cookie is being set from a page with the path /site/settings/, and you wanted all of the pages in /site/ to be able to see the cookie, you would need to add a path setting to your cookie to allow it, like this:

document.cookie="name=newvalue; path=/site/";

Note that the expiry date was left out of this setting - that is because it is optional for a cookie to have any of these parameters. Leaving out the expiry simply means that this cookie will expire when the browser next exits. The path setting in this case will allow your cookie to be viewed by any page in the /site/ directory, but not from the /other directory - to share with both of those, you would have to set your path to be just /. Remember when shortening your path, that it always starts comparing from the left side.

Using the DOMAIN property:

As web sites get larger and harder to manage, sometimes they get split up among multiple servers. One example would be the University of Windsor's web site, which forwards from www.uwindsor.ca to one of athena.uwindsor.ca, zeus.uwindsor.ca, venus.uwindsor.ca, and cronos.uwindsor.ca, to spread out the load among multiple servers. Also, sometimes a web site will decide to host content on one machine, forums on a different machine, and images on another, creating names like "www.cnn.com", "forums.cnn.com", and "images.cnn.com" to handle each - if they wish to be able to apply a cookie to be used by all three machines, they will have to force the domain property to be less specific - otherwise a cookie set on www.cnn.com would not be available on forums.cnn.com - to fix this, they would need to shorten their domain to just cnn.com. (The domain compares starting on the right side, because of the way domain names are built, with the general part at the end, and the specifics at the start.)

document.cookie="name=netvalue; domain=cnn.com";

Again, only parameters that are needed are included here. The shortened domain cnn.com will match all of www.cnn.com, forums.cnn.com, and images.cnn.com, and any of those machines would then be able to use the cookie, as long as they had the right path. To allow any file on any of the machines to use the cookie, they would have to set bot the path and the domain, like this:

document.cookie="name=tenvalue; path=/; domain=cnn.com";

The last parameter: secure

There is one last parameter which can be set on a cookie - and it's one that you will rarely use, if ever, as it is designed to tell the cookie whether it is being used on a secure web server connection or not. (Secure connections are encrypted, and use https:// at the start of the URL instead of just http://.) If you set this property, it means that your cookie will only be viewed by pages from secure connections. If you do not set it, your cookie will only be viewed from pages without secure connections. Unlike all of the other properties, the secure property has no value assigned to it - if you include it at all, it would be done like this:

document.cookie="name=tenvalue; secure";

And after that, your cookie would only be avaliable if you're reading the web page through an https connection.

Properties on the cookie:

Here is a listing of all of the properties available to be set on a cookie, and how they would be set:

cookieName=cookieValue; expires=Fri, 28 Sep 2001 20:38:49 GMT; path=/; domain=uwindsor.ca; secure

Note that this should be all in one string, on one line. Each of the sections of the cookie is separated by a semi-colon, and their purpose is as follows:

Making things easier:

Since setting and reading cookies is a very complex task, a few functions have been made available to you which will deal with these parts for you. To include these functions in your website, all you need to do is include the following tag in the start of your web page's head area:

<script type="text/javascript" language="javascript" src="http://cs.uwindsor.ca/60-270/cookies.js"></script>

This will give you access to these three pre-made JavaScript functions: setCookie(), getCookie(), and delCookie(). Here are instructions on how to use each of them:

setCookie()

getCookie()

delCookie()

For those who wish to know, the source code for the above functions is as follows:

function setCookie (name, value) { var argv = setCookie.arguments; var argc = setCookie.arguments.length; var expires = (argc > 2) ? argv[2] : null; var tempcook = name + "=" + escape (value); if (expires) { tempcook = tempcook + "; expires=" + expires.toGMTString(); } document.cookie = tempcook; } function getCookie(name) { var cookie = " " + document.cookie; var search = " " + name + "="; var setStr = null; var offset = 0; var end = 0; if (cookie.length > 0) { offset = cookie.indexOf(search); if (offset != -1) { offset += search.length; end = cookie.indexOf(";", offset) if (end == -1) { end = cookie.length; }; setStr = unescape(cookie.substring(offset, end)); }; }; return(setStr); }; function delCookie (name) { document.cookie = name + "=del;expires=Mon, 01-Jan-2000 00:00:00 GMT"; };

Examples of a cookie in use:

One example of a cookie in use would be the one used on the class website, which uses a cookie to store the viewer's prefered colour settings. To set the cookie, the viewer must go to the settings page, and select a theme from the box there. When they do, the setCookie function is run, to store their preference, and an expiry of one year from then is set, like this:

<script language="JavaScript" src="/60-270/cookies.js" type="text/javascript"></script> <script language="JavaScript" type="text/javascript" > var expDays = 365; var exp = new Date(); exp.setTime(exp.getTime() + (expDays*24*60*60*1000)); </script> <form name="setit" action="" method="get"> <select name="setthis"> <option value="blue"> Original Blue Background </option> <option value="black"> Printer-friendly Black &amp; White </option> <option value="pain"> Argh! My Eyes are burning!</option> <option value="yellow"> Pale Yellow Background </option> </select> <input type="button" value="Choose this" onclick="setCookie('setup',setthis.options[setthis.selectedIndex].value,exp);document.location='index.php'" /> </form>

Now that the cookie has been set (or not), we can read the cookie in at the top of each page, and decide which stylesheet to apply to the page based on what it contains, like this:

var sheet; var checkIt = getCookie('setup'); if (checkIt == null) {checkIt = "main";}; switch (checkIt) { case "pain": sheet = "pain.css"; break; case "black": sheet = "black.css"; break; case "yellow": sheet = "yellow.css"; break; default: sheet = "main.css"; }; document.writeln("<link rel='stylesheet' href='/60-270/" + sheet + "' type='text/css' />");

This code has to be run in the head area of the document, because the tag output by the document.writeln statement belongs in the head area as well.