Cookies with JavaScript

Cookies

Since the HTTP (HyperText Transport Protocol) protocol cannot maintain user information, cookies are a solution to save useful client side data. The implementation varies on different browsers, but we decided to use the Netscape convention, because this great enterprise developed JavaScript. Netscape Navigator holds cookies in a text file called cookies.txt; otherwise, Microsoft Internet Explorer saves them into the Cookies folder. The implementation we present is Navigator and Explorer compliant.

Notice each cookie is attached in the cookies.txt file as a line and it has the following format

name=value;expires=expirationDate;

name is the name of the cookie and value, its value. expirationDate is an optional parameter, which indicates the cookie lifetime. expirationDate, if available, has the following structure

Mon, DD-MM-YY HH:MM:SS GMT

We use the toGMTString method, belonging to the Date object, to convert dates to this format. We remarked expirationDate is an optional parameter. When it is not set up, it is removed when user exits the current browser session. When its expiration date is explicited, cookie is not deleted until this date.Cookies

DEVPapersScript

We use document.cookie to inspect and eventually get and save cookies in HTML documents. document.cookie refers a string containing all names and values of Navigator cookies.

Let us start by implementing two functions, inserted between the HEAD tags. They set and get cookies for the Internet page.

function devpapersSaveCookie(name, cookieField, expiration)
{
if (expiration==null)
var expirationDate=””;
else
expirationDate=”; expires=” + expiration.toGMTString();

document.cookie=escape(name) + “=” + escape(cookieField) + expirationDate;
}

Notice expirationDate is a variable that holds the expiration date converted to GMT date format. If the expiration date (expiration) was not set up (it means it is null), the string is “”. If it was explicited, we need to create a new string that contains the expiration date. So we concatenate the string “;expires” and the returned string of the toGMTString() method. Then, we specify the cookie for the document is called name attached to the strings value and expirationDate. The result is a format like name=value;expires=expirationDate;. See we use the escape method to encode strings. We do that because we want the cookies include also special characters as commas and spaces. The escape method returns the hexadecimal encoding of the string argument. Obviously, we will need to decode this string to read the name and value. For this, we use the unescape method.

function devpapersOpenCookie(name)
{
var search_cookie=escape(name) + “=”;

if (document.cookie.length!=0)
{
var start_cookie=document.cookie.indexOf(search_cookie);

if (start_cookie!=-1)
{
start_cookie+=search_cookie.length;
var end_cookie=document.cookie.indexOf(“;”, start_cookie)

if (end_cookie==-1)
end_cookie=document.cookie.length;

return unescape(document.cookie.substring(start_cookie, end_cookie));
}
}
}

This function returns the value of the cookie represented with name. Because name was encoded, we encode again the string and then concatenate it with the string =. For instance, if we call the function with devpapersOpenCookie(DEVpapers.com), name is the string DEVpapers.com and search_cookie is the string DEVpapers.com=. The document.cookie.length!=0 condition is equal to see if there are any cookies. Then, if is any cookie -not necessarily the one we search for-, we want to know if the cookie called name is present. We use the indexOf method to return the position or index of the string search_cookie within the string document.cookie. This method returns the beginning of the first time this entire string is found. Let us see it with an example. If we have a string called test which its value is 0123name=value (var test=”0123name=value”;), and we use the indexOf method with the test string and the substring name=value (test.indexOf(“name=value”)), it returns 4, since the first and unique time this string appears in the test string is the fourth position from 0. Notice this function returns a non-zero value if the substring is found. Otherwise, it returns -1.

Returning to our devpapersOpenCookie function, we check if the name of the cookie is in the document cookies. Remember this function is intended to return the value of the cookie called name. If the cookie is found, we increment the index start_cookie in search_cookie.length-times. We might know the length property returns the length of a string. So we do is to advance the pointer to the end of the string search_cookie, because we know following this string we find the value (name=value;expires=expirationDate;). Again, if start_cookie is 4 and search_cookie is the string name=, we assign 9 to start_cookie, because the length of the string name= is 5.

Once we find the start point of the string corresponding to the value, we need to know where it ends. If the cookie has an expiration date, it means the end of the value is just between the start_cookie position and the character ;. Let us see another example. If a string test is created with the value name=value;expires=expirationDate, and we want the get the value located between the string name= and ;, we use start_cookie (5 in this case) and end_cookie (10 in this case, because the string ; is found) to restrict the string test to the string value.

Try with this simple example

var test=”name=value;expires=expirationDate”;
var start_cookie=test.indexOf(“name=”);
var end_cookie=test.indexOf(“;”, start_cookie);

start_cookie+=”name=”.length;

// will alert the string value
alert(test.substring(start_cookie, end_cookie));

However, if the cookie was not set up with an expiration date, it has not got the string ;. Then, it means the end of the value is the end of the line of the cookie. And then, we set end_cookie with the length of the cookie (document.cookie.length). Finally, because the value was encoded with escape, we need to decode the string using unescape. As you might suspect, the substring method takes the substring between the first parameter counting from 0 and the second parameter, not included.

We create another function, destined to insert a cookie named DEVpapers.com. We want this cookie stays in the client hard disk for a day, and 1000*60*60*24 represent the number of milliseconds within a day. If we would like the cookie stays for a year, we might insert 1000*60*60*24*365 instead.

function devpapersSave(cookieField)
{
var today=new Date();
var expiration=new Date();

expiration.setTime(today.getTime() + 1000*60*60*24);
devpapersSaveCookie(“DEVpapers.com”, cookieField, expiration);
}

Example

It is time to join the script and the web page code. Insert the script in the HEAD tag. You do not need to type any line, the example is available to download.

This example saves the value of a form field in a cookie called DEVpapers.com and each time the user loads the document, a pop up alert appears with the value of the cookie. It will happen until the expiration date.

The function added is

function devpapersRead()
{
var visited=devpapersOpenCookie(“DEVpapers.com”);

if (visited!=null)
alert(visited);
}

Then, we insert the following HTML code to invoke the JavaScript functions. As we said, every time the document is loaded (handled with the onLoad event), the function devpapersRead is called, and it alerts the user with the value of the cookie, if set. And each time users submit the form, the cookie is updated with new values.

<body bgcolor=”#FFFFFF” onLoad=”devpapersRead()”>
<form action=”” name=”cookieForm” onSubmit=”devpapersSave(document.cookieForm.cookieField.value)”>
<input type=”text” name=”cookieField”>
<input type=”submit” name=”cookieButton” value=”Cookie”>
</form>

Conclusion

Using JavaScript, we can handle useful information to, for example, personalise web sites. We made this example trivial for educational purposes –even we alert the value of the cookie-, but we can handle more useful data.