How to Deal with Cookies in JavaScript
For years, many web developers have needed to store data on the client. Before the advent of HTML5 and its new mechanisms, every developer used cookies to achieve this goal. Unfortunately, working with cookies in JavaScript can cause a lot of headaches. This article discusses what cookies are, and how you can build functions to create, retrieve, and delete them.
What are Cookies?
A cookie is a piece of data which is sent from a website and stored locally by the user’s browser. Cookies are needed because HTTP is stateless. This means that HTTP itself has no way to keep track of a user’s previous activities. One way to create state is by using cookies.
To Use Cookies or Not to Use Cookies
Today most, if not all, websites worldwide use cookies. However, cookies are rather limited, as they can only store up to 4KB of data. Moreover, many developers claim that because cookies are sent to the server with each HTTP request, large ones can consume considerable network bandwidth, hurting performance. Another important criticism against cookies has been written by Remy Sharp in the co-authored book Introducing HTML5. This can be potentially catastrophic for mobile connections. Another important point to keep in mind is that if you have European visitors, then your site must comply with the EU E-Privacy Directive from May 26, 2012. If you never heard about this, take a look at Why Your Site is Now Illegal in Europe.
In recent years, a lot of thought has been put towards finding an alternative to cookies. Thanks to HTML5, some new techniques have appeared on the scene. The first one is Web Storage API, which has methods for storing name-value pairs. For an overview of the Web Storage API, I advise you to read An Overview of the Web Storage API. The second alternative is the Web SQL Database API, which stores data in databases that can be queried using a variant of SQL. While Web SQL is well supported, the standard is no longer being actively maintained. Last, but not least, is the Indexed Database API, that defines a database of records holding simple values and hierarchical objects. You can read more about IndexedDB in Up Close and Personal with HTML5 IndexedDB. Unfortunately, IndexedDB isn’t widely supported, so you probably shouldn’t rely on it.
No matter your preference, there are several important points to understand. While all of these APIs provide local storage similar to cookies, they do not send their data back to the server. So, in most cases you will use both cookies and one of the storage APIs. Technically, the same effects could be achieved using AJAX, but this over complicates the task and requires additional code.
How Cookies are Made
The structure of a cookie is really simple. It’s nothing but several key-value pairs. Pairs are separated by semicolons, while the equal sign character separates the key from its value. A cookie can optionally have an expiration date, after which it’s deleted. If an expiration date isn’t provided, the cookie will last until the session or browser is closed. If you set the expiration date in the past, the browser will delete the cookie. Please note that the format of the date is important, as it has to be in UTC/GMT. Moreover, you can specify a domain and a path where the cookie can be read and written. By default the path value is ‘/’, meaning that the cookie is visible to all paths in a given domain. If you don’t specify the domain, it will belong to the page that set the cookie. The way you set these data also matter. The order should be:
key-value;expiration_date;path;domain;
.
The following example shows a cookie that is accessible in all the paths of the domain, and has just one key-value pair.
visits=3; path=/;
The following example shows a cookie that is accessible in all the paths of the domain (by default), and expires on October 31, 2012 at 11 a.m..
last-visit=Mon, 15 Oct 2012 19:36:00 GMT; expires=Wed, 31 Oct 2012 11:00:00 GMT;
Scripting Cookies
So far, I have explained what cookies are, as well as some of their pros and cons. Now it’s time to see what functions JavaScript exposes to work with them. Unfortunately, the first thing I have to say is that JavaScript doesn’t have native methods to easily work with cookies. JavaScript can create, retrieve, and delete cookies using the document.cookie
property, but it’s not really a pleasure to use. Every time you are forced to deal with split()
, substring()
and for
loops. Please note that while you can treat document.cookie
like a string variable, it’s actually more than that. For example, take the following script:
document.cookie = "visits=3; path=/;";
document.cookie = "last-visit=Mon, 15 Oct 2012 19:36:00 GMT; expires=Wed, 31 Oct 2012 11:00:00 GMT;";
If you then print document.cookie
, you’ll get an unexpected result as shown below:
console.log(document.cookie);
// print visits=3; last-visit=Mon, 15 Oct 2012 19:36:00
By now, you’ve seen the hardships of dealing with cookies in JavaScript. So, it’s time to create our own functions to easily manage them. The following function will help you to create a cookie. Please note that the expires parameter can be either an instance of a Date
object or a number which indicates the number of days. The latter can be a negative number, which sets the expiration date in the past.
function createCookie(name, value, expires, path, domain) {
var cookie = name + "=" + escape(value) + ";";
if (expires) {
// If it's a date
if(expires instanceof Date) {
// If it isn't a valid date
if (isNaN(expires.getTime()))
expires = new Date();
}
else
expires = new Date(new Date().getTime() + parseInt(expires) * 1000 * 60 * 60 * 24);
cookie += "expires=" + expires.toGMTString() + ";";
}
if (path)
cookie += "path=" + path + ";";
if (domain)
cookie += "domain=" + domain + ";";
document.cookie = cookie;
}
You can call this function as shown below.
createCookie("website", "audero.it", new Date(new Date().getTime() + 10000));
createCookie("author", "aurelio", 30);
Now that you set a cookie, you need to be able to retrieve them. You’ll do it using a given key and the following getCookie()
function. It returns the value of the key if it’s found, and null
otherwise.
function getCookie(name) {
var regexp = new RegExp("(?:^" + name + "|;\s*"+ name + ")=(.*?)(?:;|$)", "g");
var result = regexp.exec(document.cookie);
return (result === null) ? null : result[1];
}
Using getCookie()
is very simple. You simply pass the key as a parameter like as shown below.
console.log(getCookie("author")); // print aurelio
console.log(getCookie("nothing")); // print null
Now we need the last function to delete a cookie. The function shown is very simple because it relies on getCookie()
to test if the given name is set, and createCookie()
to set the expiration date in the past.
function deleteCookie(name, path, domain) {
// If the cookie exists
if (getCookie(name))
createCookie(name, "", -1, path, domain);
}
Given that function, to delete a cookie you can simply write:
deleteCookie("author");
console.log(getCookie("author")); // now print null
Using the functions shown, you’ll be able to easily manage cookies. The web is also full of plenty of other cookie handling functions. Of the plethora of functions you can find, I’d like to show the ones written by Peter-Paul Koch (P.P.K.), a guru of front-end development, on quirksmode.com. I’d like to thank him for allowing me to include them in this article. P.P.K’s function to create a cookie is shown below.
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
Similarly, to retrieve a cookie, use the following function.
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
And this is the function to delete a cookie.
function eraseCookie(name) {
createCookie(name,"",-1);
}
Conclusions
Throughout this article you learned what cookies are, how they are made, and their strengths and weaknesses. You’ve also seen how you can deal with cookies using custom functions. As I also pointed out in my previous article, JavaScript lacks some basic utility functions. Luckily, you can easily build your own or search the web to solve your problems.