Rate this page

Flattr this

Create a cookie in JavaScript

Tested on

Firefox (3.0, 3.6, 30, 31)
Chrome (5, 34, 36)
IE (6, 7, 8, 11)

Objective

To create a cookie from within a web page using JavaScript

Scenario

Suppose that you wish to create a session cookie named foo. Its value should be set to the content of the variable named cookieValue, which contains a Unicode character string. You would normally expect the string to be composed of printable characters from the Basic Latin block (%20 to %7E), however you want to avoid placing any hard constraints on its content.

The cookie need only be readable from the page that created it, and does not contain security-sensitive information.

Method

Overview

The basic method described here has three steps:

  1. Optionally, encode the cookie value to avoid forbidden characters.
  2. Express the cookie as a name-value pair.
  3. Assign the resulting string to document.cookie.

For example:

document.cookie = 'foo=' + encodeURIComponent(cookieValue);

You may also need to do some or all of the following:

Note that a cookie created via HTTP with the httponly attribute cannot be overwritten using the JavaScript API.

Optionally, encode the cookie value to avoid forbidden characters

For portability the value of a cookie should be limited to printable US-ASCII characters and should not include any of the following:

Code Name
%20 space
%22 quotation mark
%2C comma
%3B semicolon
%5C backslash

It may be that the nature of the content ensures this as a matter of course, but otherwise the value will need to be encoded in some way. Commonly-used methods include:

Since cookies do not normally need to be readable by third-party code you are free to choose an encoding scheme to suit your needs. RFC 6265 offers base64 as an example, but does not mandate any particular method. In this instance, given the nature of the cookie value described in the scenario above, encodeURIComponent would be an appropriate choice:

encodeURIComponent(cookieValue);

Express the cookie as a name-value pair

The cookie should then be expressed as a name-value pair of the form <name>=<value>:

var cookieString = 'foo=' + encodeURIComponent(cookieValue);

This is the textual representation of a cookie with no attributes, and could be used (for example) in an HTTP Set-Cookie header.

Assign the name-value pair to document.cookie

From JavaScript, cookies can be set or inspected using the cookie property of the global document object. Be aware that this does not behave like an ordinary variable:

There is no need to splice the new cookie into the existing list (and in fact you must not do that). Rather, assignment of the key-value pair prepared above will suffice:

document.cookie = cookieString;

If there is an existing cookie with the same name, path and domain then it will be replaced. Otherwise, a new cookie is created.

Variations

Define the scope of the cookie (path and/or domain)

By default, a cookie created by a web page at a given URI is accessible to other pages in the same directory, and to pages in subdirectories of the same directory. For example, a cookie created by /foo/bar.html is accessible to /foo/baz.html and /foo/qux/baz.html, but not to /baz.html.

This behavior has the virtue of being safe when there are multiple independent websites operating from the same domain, but in practice most modern websites place cookies at the root of the domain so that they are visible from all paths. You can arrange this by setting the path attribute:

var cookieString = 'foo=' + encodeURIComponent(cookieValue);
cookieString += ';path=/';
document.cookie = cookieString;

With regard to the domain, the default behaviour is to make the cookie visible only to pages within the same domain and not to any subdomains. This is appropriate for most websites. The alternative is to explicitly set the domain attribute, in which case subdomains are included. For example:

var cookieString = 'foo=' + encodeURIComponent(cookieValue);
cookieString += ';path=/';
cookieString += ';domain=example.com';
document.cookie = cookieString;

would make the cookie visible from subdomains such as www.example.com in addition to example.com itself. This would be appropriate if, for example, you wanted to implement cookie-based single sign-on authentication throughout a collection of subdomains.

(Be aware that most web browsers will prevent you from setting cookies on domains such as com or co.uk for security reasons. As a rule of thumb, you should not try to associate domains in this way unless you own the parent domain.)

Specify when the cookie should expire

Cookies are non-persistent by default, meaning that they live for the duration of a browser session. They can be made to live longer by appending a max-age attribute which specifies the required lifespan in seconds. For compatibility with Internet Explorer you may also want to append an expires attribute. (max-age takes precedence if it is present and supported.)

The required attribute formats are max-age=<max-age> and expires=<date>, where <max-age> is the maximum number of seconds for which the cookie should live, and <date> is the date when the cookie should expire. The preferred format for the expiry date is an RFC 1123 date string. For example, if a cookie were being set at Sun, 20 Jul 2014 12:00:00 GMT and was supposed to last for one day then the appropriate attribute strings would be max-age=86400 and expires=Mon, 21 Jul 2014 12:00:00 GMT. For expiry after maxAge seconds:

var cookieString = 'foo=' + encodeURIComponent(cookieValue);
var maxAge = 3600; // the required lifespan in seconds
var expiryDate = new Date();
expiryDate.setTime(expiryDate.getTime() + maxAge * 1000);
cookieString += ';max-age=' + maxAge;
cookieString += ';expires=' + expiryDate.toUTCString();
document.cookie = cookieString;

You should avoid using Date.toGMTString to encode the expiry date, as that method is deprecated.

Be aware that web browsers are not obliged to keep cookies until their requested expiry dates (or indeed, to accept them in the first place). RFC 6265 cautions against gratuitously long expiry periods, due to the adverse effect on user privacy.

Limit the cookie to transmission over secure channels

By default, a cookie will be presented as part of any HTTP request with a matching domain and path. Consequently, it is possible for information sent to the client via a secure connection to be returned using plain HTTP. This is obviously not a desirable outcome if the content is security sensitive.

Setting the secure attribute of the cookie prevents this from happening:

var cookieString = 'foo=' + encodeURIComponent(cookieValue);
cookieString += ';secure';
document.cookie = cookieString;

See Also

Further Reading

(Note that RFC 6265 and the Netscape specification technically refer to setting cookies via HTTP and not from JavaScript. In practice you can overlook this distinction for most purposes, and must do if you want more detail than the very limited amount of documentation available for the JavaScript API.)

Tags: cookie | javascript