Cookies

Objectives

Background

Cookies are small packets of information that can be stored on the client computer. They provide a way of storing "state." Cookies are commonly used for shopping carts and user preferences. They are only visible to the site that stored them. They are sent as part of the HTTP protocol to the server where CGI programs can manipulate them. JavaScript can also be used to manipulate cookies.

Cookies are retrieved by JavaScript through the document's cookie property.

Storing a Cookie

Cookies are stored with name/value pairs. The escape() function is often used on the data to be stored because it will translate illegal characters into characters that can be stored. When the escape function is used to store information, the unescape() function should be used to read that information. Unescape translates the characters back to what they originally were.

Storing a cookie is as simple as:
document.cookie = "age=" + 19;

A cookie has certain attributes that can be set the same way other data is written to a cookie. These attributes are: domain, path, expires, and secure. The path attribute can be changed if you want your web pages on other directories to be able to read the cookie. The domain can be set if your business has multiple servers in a domain and you wish to make the cookie available to all of them. The secure attribute can be set to provide for encrypted cookie transmission. The expires attribute is used to tell the browser when to delete a cookie.

When cookies are stored as was done in the previous example, separate entries (cookies) are made for each data item stored. There are limitations to cookie storage, though. Web browsers only have to allow 300 cookies total, and only 20 per web server. There is also a 4096 character limit on cookies. If your web site grows large and uses cookies for a number of things, the 20 cookie per server limit could become a problem. For this reason, many web sites will package all their information up into one big cookie.

Often times, a customer will be identified with a unique number stored in a cookie on the client machine, and that number is used to look up the relevant customer information in a database stored on the server. That reduces what has to be stored on the client machine, reduces dependence on the client machine, and makes it easier to reassociate a customer and their information if they login from a different client machine.

Reading a Cookie

The document.cookie property returns a string consisting of ALL the cookies that apply to the document. Even if they are stored internally as separate entries, they are retrieved as one long string. This means that the JavaScript for reading cookies is not simple. Demonstration scripts will be provided for writing, reading, and deleting cookies.

Modifying a Cookie

Cookie contents may be modified by writing the cookie with the exact same attributes, but with different values.

Deleting a Cookie

A cookie may be deleted by writing the cookie with an expiration date in the past.

Demonstration Scripts

Writing a cookie

Sample: cook01.html

<script>
document.cookie = "Color=green";
</script>

Reading a cookie

Sample: cook02.html

<h3>The cookie is:
<script>
document.write(document.cookie);
</script>
</h3>

Persistent cookies

The cookie demonstrated in the last two scripts had no persistence. It went away as soon as the browser was shut down. If you want a persistent cookie, you have to set the expiry date into the future. You can read what this script stores using the same script previously used to read the document cookie.

Sample: cook03.html

<script>
var now = new Date();
var oneWeek = 1000 * 60 * 60 * 24 * 7; // milliseconds per week
var expDate = new Date(now.getTime() + oneWeek);
document.cookie = "Color=blue;expires=" + expDate.toGMTString();
</script>

Changing cookie values

Sample: cook04.html

<script>
document.cookie = "Color=red";
</script>

Setting multiple values

This script stores multiple values, but they are not persistent. If other values stored in the cookie have expiry dates in the future, they will persist past the browser shutdown, but these won't.

Sample: cook05.html

<script>
document.cookie = "ID=4762";
document.cookie = "limit=57";
</script>

Reading/parsing multiple cookies

This script demonstrates how you can work with multiple cookies. It relies on the fact that cookie name/value pairs are separated by semicolons, and names and values are separated by the "=" character.

Sample: cook06.html

<script>
if (!document.cookie) {
    document.writeln('<p>No cookie was found.</p>');
} else {
    document.writeln('<p>The cookie values are:</p>');
    document.writeln('<ol>');
    cook = document.cookie.split('; ');
    for (i=0; i<cook.length; i++) {
        document.writeln('<li>' + cook[i].split('=')[0] + ' ('
            + cook[i].split('=')[1] + ')</li>');
    }
    document.writeln('</ol>');
}
</script>

Nonstandard values

Certain characters in the values of cookies can really mess things up. This is much the same problem as having invalid characters in a URL. The functions escape and unescape are provided to help out with this problem. escape encodes a string so it can be safely stored, and unescape decodes the string back to its original form.

Sample: cook07.html

<script>
document.cookie = "Name=Dave;The Wonder Dog = Me";
cook = document.cookie.split(';');
document.writeln('<p>Cookie with problems: '
    + document.cookie + '</p><ol>');
for (i=0; i<cook.length; i++) {
    document.writeln('<li>' + cook[i].split('=')[0] + ' ('
        + cook[i].split('=')[1] + ')</li>');
}
document.writeln('</ol>');

document.cookie = "Name=" + escape("Dave;The Wonder Dog = Me");
cook = document.cookie.split(';');
document.writeln('<p>Problems fixed: '
    + document.cookie + '</p><ol>');
for (i=0; i<cook.length; i++) {
    document.writeln('<li>' + cook[i].split('=')[0] + ' ('
        + unescape(cook[i].split('=')[1]) + ')</li>');
}
document.writeln('</ol>');

</script>

Deleting a cookie

Deleting cookies is as simple as setting their expiration date in the past.

Sample: cook08.html

<script>
var now = new Date();
var expDate = new Date(now.getTime() - 1000000);
document.cookie = "Color=silver;expires=" + expDate.toGMTString();
document.writeln('<p>' + document.cookie + '</p>');
</script>

Automating cookie saving

Sample: cook09.html

<script>
function saveCookie(name, value, daysUntilExpire) {
    if (!name || !value) return;
    var now = new Date();
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    var expDate = new Date(now.getTime()
        + daysUntilExpire * millisecondsPerDay);
    document.cookie = name + "=" + escape(value)
        + ";expires=" + expDate.toGMTString()
        + ";path=/";
}
</script>

Automating cookie reading

Sample: cook10.html

<script>
function readCookie(name) {
    if (!name) return null;
    var cook = document.cookie.split('; ');
    for (var i=0; i<cook.length; i++) {
        if (name == cook[i].split('=')[0]) {
            return unescape(cook[i].split('=')[1]);
        }
    }
    return null;
}
</script>

Automating cookie deletion

Sample: cook11.html

<script>
function deleteCookie(name) {
    if (!name) return;
    var now = new Date();
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    // set expiry date to arbitrary date in past
    var expDate = new Date(now.getTime()
        - 7 *  millisecondsPerDay);
    document.cookie = name + "=;expires="
        + expDate.toGMTString() + ";path=/";
}
</script>

Deleting all cookies

Sample: cook12.html

<script>
function deleteAllCookies() {
    var now = new Date();
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    // set expiry date to arbitrary date in past
    var expDate = new Date(now.getTime()
        - 7 *  millisecondsPerDay);
    var cook = document.cookie.split('; ');
    for (var i=0; i<cook.length; i++) {
        var cname = cook[i].split('=')[0];
        // var cval = cook[i].split('=')[1];
        document.cookie = cname + "=;expires="
            + expDate.toGMTString() + ";path=/";
    }
}
</script>

A cookie library