|Firefox (3.0, 3.6, 30, 31)|
|Chrome (5, 34, 36)|
|IE (6, 7, 8, 11)|
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.
The basic method described here has three steps:
- Optionally, encode the cookie value to avoid forbidden characters.
- Express the cookie as a name-value pair.
- Assign the resulting string to
document.cookie = 'foo=' + encodeURIComponent(cookieValue);
You may also need to do some or all of the following:
- Define the scope of the cookie (path and/or domain).
- Specify when the cookie should expire.
- Limit the cookie to transmission over secure channels.
Note that a cookie created via HTTP with the
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:
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:
encodeURIComponent, which had been part of the ECMAScript standard since 1999 (3rd edition), and which escapes all of the characters that need to be. Unicode strings are handled appropriately.
Window.atobfor encoding to the base64 variant. At the time of writing it had not been formally standardised, however brower support is generally good (with the notable exception of Internet Explorer prior to IE10).
Window.btoadoes not support the encoding of arbitrary Unicode characters without first converting them to UTF-8.
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:
Express the cookie as a name-value pair
The cookie should then be expressed as a name-value pair of the form
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
Assign the name-value pair to document.cookie
cookie property of the global
document object. Be aware that this does not behave like an ordinary variable:
- When read it returns a semicolon-separated list of all cookies that are associated with the current document.
- When written to it expects data for a single cookie, which is created or updated as appropriate. Other cookies are left unchanged.
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.
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/qux/baz.html, but not to
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
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
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> 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
expires=Mon, 21 Jul 2014 12:00:00 GMT.
For expiry after
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.
secure attribute of the cookie prevents this from happening:
var cookieString = 'foo=' + encodeURIComponent(cookieValue); cookieString += ';secure'; document.cookie = cookieString;
- Document.cookie, Web API Interfaces, Mozilla Developer Network
- A. Barth, HTTP State Management Mechanism, RFC 6265, IETF, April 2011
- Persistent Client State HTTP Cookies, Netscape (historical specification)
- Cookies, QuirksMode