[ Team LiB ] Previous Section Next Section

1.9 Reading and Writing Strings for Cookies

NN 2, IE 3

1.9.1 Problem

You want to use cookies to preserve string data from one page visit to the next.

1.9.2 Solution

Use the cookies.js library shown in the Discussion as a utility for saving and retrieving cookies. To set a cookie via the library, invoke the setCookie( ) function, passing, at a minimum, the cookie's name and string value as arguments:

setCookie ("userID", document.entryForm.username.value);

To retrieve a cookie's value, invoke the library's getCookie( ) function, as in:

var user = getCookie("userID");

1.9.3 Discussion

Example 1-1 shows the code for the entire cookies.js library.

Example 1-1. cookies.js library
// utility function to retrieve an expiration date in proper
// format; pass three integer parameters for the number of days, hours,
// and minutes from now you want the cookie to expire (or negative
// values for a past date); all three parameters are required,
// so use zeros where appropriate
function getExpDate(days, hours, minutes) {
    var expDate = new Date( );
    if (typeof days =  = "number" && typeof hours =  = "number" && 
        typeof hours =  = "number") {
        expDate.setDate(expDate.getDate( ) + parseInt(days));
        expDate.setHours(expDate.getHours( ) + parseInt(hours));
        expDate.setMinutes(expDate.getMinutes( ) + parseInt(minutes));
        return expDate.toGMTString( );
    }
}
   
// utility function called by getCookie( )
function getCookieVal(offset) {
    var endstr = document.cookie.indexOf (";", offset);
    if (endstr =  = -1) {
        endstr = document.cookie.length;
    }
    return unescape(document.cookie.substring(offset, endstr));
}
   
// primary function to retrieve cookie by name
function getCookie(name) {
    var arg = name + "=";
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    while (i < clen) {
        var j = i + alen;
        if (document.cookie.substring(i, j) =  = arg) {
            return getCookieVal(j);
        }
        i = document.cookie.indexOf(" ", i) + 1;
        if (i =  = 0) break; 
    }
    return "";
}
   
// store cookie value with optional details as needed
function setCookie(name, value, expires, path, domain, secure) {
    document.cookie = name + "=" + escape (value) +
        ((expires) ? "; expires=" + expires : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
}
   
// remove the cookie by setting ancient expiration date
function deleteCookie(name,path,domain) {
    if (getCookie(name)) {
        document.cookie = name + "=" +
            ((path) ? "; path=" + path : "") +
            ((domain) ? "; domain=" + domain : "") +
            "; expires=Thu, 01-Jan-70 00:00:01 GMT";
    }
}

The library begins with a utility function (getExpDate( )) that your scripts use to assist in setting an expiration date for the cookie. A second utility function (getCookieVal( )) is invoked internally during the reading of a cookie.

Use the getCookie( ) function in your scripts to read the value of a named cookie previously saved. The name you pass to the function is a string. If no cookie by that name exists in the browser's cookie filing system, the function returns an empty string.

To save a cookie, invoke the setCookie( ) function. Required parameters are the first one for the name of the cookie and the second, which contains the value to be preserved. If you intend the cookie to last beyond the user quitting the browser, be sure to set an expiration date as the third parameter. Filter the expiration time period through the getExpDate( ) function shown earlier so that the third parameter of setCookie( ) is in the correct format.

One last function, deleteCookie( ), lets you delete an existing cookie before its expiration date. The function is hardwired to set the expiration date to the start of the JavaScript date epoch.

Load the library into your page in the head portion of the document:

<script type="text/javascript" src="cookies.js"></script>

All cookie values you save must be string values; all cookie values you retrieve are string values.

A browser cookie is the only way to preserve a string value on the client between visits to your web site. Scripts on your page may read only cookies that were saved from your domain and server. If you have multiple servers in your domain, you can set the fifth parameter of setCookie( ) to share cookies between servers at the same domain.

Browsers typically limit capacity to 20 name/value pairs of cookies per server; a cookie should be no more than 4,000 characters, but more practically, the value of an individual named cookie should be less than 2,000 characters. In other words, cookies are not meant to act as high-volume data storage facilities on the client. Also, browsers automatically send domain-specific cookie data to the server as part of each page request. Keep the amount of data small to limit the impact on dial-up users.

When you save a cookie, the name/value pair resides in the browser's memory. The data, if set to expire some time in the future, is written to the cookie filesystem only when the browser quits. Therefore, don't be alarmed if you don't see your latest entry in the cookie file while the browser is still running. Different browsers save their cookies differently (and in different places in each operating system). IE stores each domain's cookies in its own text file, while Netscape gangs all cookies together in a single text file.

All of this cookie action is made possible through the document.cookie property. The purpose of the cookies.js library is to act as a friendlier interface between your scripts and the document.cookie property, which isn't as helpful as it could be in extracting cookie information. Although you can save a cookie with several parameters, only the value of a cookie is available for reading—not the expiration date, path, or domain details.

Cookies are commonly used to preserve user preference settings between visits. A script near the top of the page reads the cookie to see if it exists, and, if so, applies settings to various content or layout attributes while the rest of the page loads. Recipe 12.4 shows how this can work to let users select a relative font size and preserve the settings between visits. For example, the function that preserves the user's font size choice saves the value to a cookie named fontSize, which is set to expire in 180 days if not updated before then:

setCookie("fontSize", styleID, getExpDate(180, 0, 0));

The next time the user visits, the cookie is read while the page loads:

var styleCookie = getCookie("fontSize");

With the information from the cookie, the script applies the previously selected style sheet to the page. If the cookie was not previously set, the script assigns a default style sheet to use in the interim.

Just because cookies can store only strings, don't let that get in the way of preserving information normally stored in arrays or custom objects. See Recipe 3.12 and Recipe 8.14 for ways to convert more complex data types to strings for preservation, and then restore their original form after retrieval from the cookie on the next visit.

1.9.4 See Also

Recipe 10.4 for passing data between pages via cookies; Recipe 12.4 for an example of using cookies to preserve a user's style preference; Recipe 3.12 and Recipe 8.14 for ways of converting arrays and objects to cookie string values.

    [ Team LiB ] Previous Section Next Section