Skip to content

ES6 - Cookies

Cookies are small pieces of data that websites store on a user’s computer (or mobile device) through the web browser. They are a fundamental mechanism for maintaining state over the stateless HTTP protocol, enabling features like session management (e.g., keeping users logged in), personalization (e.g., user preferences), and tracking user behavior.

  1. Server Sends Cookie: When a user visits a website, the server can send a Set-Cookie HTTP header in its response. This header contains the cookie’s name, value, and optional attributes.
  2. Browser Stores Cookie: If the browser’s settings allow, it stores the cookie.
  3. Browser Sends Cookie: On subsequent requests to the same domain (and path, depending on cookie attributes), the browser automatically includes the relevant cookies in a Cookie HTTP header sent to the server.
  4. Server Reads Cookie: The server can then read the cookie data to identify the user, retrieve session information, or customize the response.
  • Name=Value: The actual data stored in the cookie. This is the only mandatory part.
  • Expires=date: Specifies the expiration date and time for the cookie. If omitted, the cookie becomes a session cookie and is deleted when the browser closes. The date should be in UTC (GMT) format.
  • Max-Age=seconds: An alternative to Expires, specifying the cookie’s lifetime in seconds. If both Expires and Max-Age are set, Max-Age takes precedence.
  • Domain=domain_name: The domain for which the cookie is valid. If not specified, it defaults to the host of the current document URL (but not subdomains).
  • Path=path: The URL path for which the cookie is valid. If not specified, it defaults to the current path of the document that set the cookie.
  • Secure: If this attribute is present, the cookie will only be sent over HTTPS connections.
  • HttpOnly: If this attribute is present, the cookie cannot be accessed by client-side JavaScript (document.cookie). This helps mitigate cross-site scripting (XSS) attacks.
  • SameSite=Strict|Lax|None: Controls whether cookies are sent with cross-site requests, providing some protection against cross-site request forgery (CSRF) attacks. None requires the Secure attribute.

JavaScript can interact with cookies (that are not HttpOnly) using the document.cookie property. This property allows you to read, create, modify, and delete cookies associated with the current web page.

To create or update a cookie, you assign a string to document.cookie. The string must be in the format name=value; expires=UTCString; path=/; SameSite=Lax etc.

Important Note on Encoding: Cookie values cannot contain semicolons, commas, or whitespace. It’s crucial to encode cookie values using encodeURIComponent() before storing them and decode them with decodeURIComponent() when reading. The old escape() and unescape() functions are deprecated and should not be used.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cookie Write Example</title>
<script>
function setUsernameCookie() {
const usernameInput = document.getElementById('username');
if (!usernameInput.value) {
alert('Please enter a username!');
return;
}
const username = encodeURIComponent(usernameInput.value);
const expiresDate = new Date();
expiresDate.setDate(expiresDate.getDate() + 7); // Expires in 7 days
document.cookie = `username=${username}; expires=${expiresDate.toUTCString()}; path=/; SameSite=Lax`;
document.getElementById('output').textContent = `Cookie set: username=${username}`;
}
</script>
</head>
<body>
<h2>Set User Preference</h2>
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<button onclick="setUsernameCookie()">Set Cookie</button>
<p id="output"></p>
</body>
</html>

After running this HTML, if you enter a username and click ‘Set Cookie’, a cookie named ‘username’ will be stored in your browser.

document.cookie returns a string containing all cookies accessible to the current page, separated by semicolons (e.g., name1=value1; name2=value2). You need to parse this string to get individual cookie values.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cookie Read Example</title>
<script>
function getCookie(name) {
const cookieString = document.cookie;
const cookies = cookieString.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.startsWith(name + '=')) {
return decodeURIComponent(cookie.substring(name.length + 1));
}
}
return null; // Cookie not found
}
function displayUsername() {
const savedUsername = getCookie('username');
const outputElement = document.getElementById('savedUsername');
if (savedUsername) {
outputElement.textContent = `Welcome back, ${savedUsername}!`;
} else {
outputElement.textContent = 'No username cookie found.';
}
}
</script>
</head>
<body onload="displayUsername()">
<h2>User Greeting</h2>
<p id="savedUsername"></p>
<p><em>Try setting a username cookie from the 'Writing a Cookie' example first.</em></p>
</body>
</html>

When this page loads, it will attempt to read the ‘username’ cookie and display a greeting if found.

As shown in the ‘Writing a Cookie’ example, you can set an expiry date using the expires attribute with a UTC date string, or Max-Age with seconds. If neither is set, it’s a session cookie.

Section titled “Example: Setting a cookie that expires in one hour.”
const now = new Date();
now.setTime(now.getTime() + (60 * 60 * 1000)); // 1 hour in milliseconds
document.cookie = `myKey=myValue; expires=${now.toUTCString()}; path=/`;
// Or using Max-Age:
document.cookie = `myKey=myValue; Max-Age=3600; path=/`; // 3600 seconds = 1 hour

To delete a cookie, you set its expires attribute to a past date or Max-Age to 0 or a negative value. You must also specify the same path and domain attributes that were used when the cookie was set.

function deleteCookie(name) {
// Set expiry date to the past
// Ensure path and domain match how the cookie was set. If not specified, they might default.
// For simplicity, assuming path is '/'
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
// Or using Max-Age
// document.cookie = name + '=; Max-Age=0; path=/';
console.log(`Cookie '${name}' deletion attempted.`);
}
// To use it:
// deleteCookie('username');

Modern Alternatives and Security Considerations

Section titled “Modern Alternatives and Security Considerations”
  • LocalStorage and SessionStorage: For storing data purely on the client-side without sending it to the server with every request, the Web Storage API (localStorage and sessionStorage) offers a more modern and often more convenient interface with larger storage capacity.
  • Security: - HttpOnly: Always use HttpOnly for cookies that don’t need to be accessed by client-side JavaScript (e.g., session tokens). This is set by the server. - Secure: Use the Secure attribute to ensure cookies are only sent over HTTPS. This is set by the server or when creating cookies in JS for secure origins. - SameSite: Use SameSite attribute (Strict, Lax, or None) to control when cookies are sent with cross-origin requests, helping to prevent CSRF attacks. This is set by the server or when creating cookies in JS. - Data Sensitivity: Avoid storing sensitive information in cookies. If necessary, ensure it’s encrypted and handled securely.
  • Cookie Size: Cookies are limited in size (typically around 4KB per cookie) and number (around 20-50 cookies per domain, depending on the browser).
  • Performance: Sending cookies with every HTTP request can add overhead, especially if cookies are numerous or large. Consider if the data truly needs to be sent to the server on every request.

For more detailed information about cookies and their attributes, consult the MDN Web Docs: