Problem: Restrictions on Cookie Characters
When creating cookies for web applications, you need to know about character limits. Not all characters can be used in cookie names and values. This can cause problems if used wrongly. Knowing these limits is key for cookies to work well and to avoid security risks.
Browser Implementation of Cookie Character Restrictions
Common Browser Practices
Web browsers handle cookie character restrictions similarly to follow web standards. Here are some common practices:
URL encoding of special characters
Browsers apply URL encoding to special characters in cookie values. This converts characters not allowed in URLs into a safe format.
Character | URL Encoded |
---|---|
Space | %20 |
= | %3D |
& | %26 |
+ | %2B |
/ | %2F |
Example: Setting a cookie with special characters
document.cookie = "user_info=John Doe & Co.; path=/";
// Browser stores it as: user_info=John%20Doe%20%26%20Co.
Handling of non-ASCII characters
Most browsers support UTF-8 encoding for non-ASCII characters in cookie values. It's best to encode these characters manually:
Example: Encoding non-ASCII characters
const userName = "José";
document.cookie = `user=${encodeURIComponent(userName)}; path=/`;
// Browser stores it as: user=Jos%C3%A9
Browser-Specific Limitations
Browsers generally follow similar practices, but there can be differences in how they handle cookies.
Tip: Browser cookie limitations
- Chrome: Up to 180 cookies per domain, 4096 bytes per cookie
- Firefox: Up to 150 cookies per domain, 4097 bytes per cookie
- Safari: Up to 600 cookies total, 4093 bytes per cookie
- Internet Explorer: Up to 50 cookies per domain, 4096 bytes per cookie
Strategies for Working with Browser Limitations
- Split large data into multiple cookies
Example: Splitting large data into multiple cookies
function setLargeCookie(name, value) {
const maxLength = 4000;
const parts = Math.ceil(value.length / maxLength);
for (let i = 0; i < parts; i++) {
const part = value.substr(i * maxLength, maxLength);
document.cookie = `${name}_${i}=${part}; path=/`;
}
}
// Usage
setLargeCookie("user_data", "very_long_string_of_user_data");
- Use local storage for client-side data that doesn't need to be sent with every request
Example: Using local storage for large data
// Storing large data in local storage
localStorage.setItem('user_preferences', JSON.stringify(largeUserPreferencesObject));
// Retrieving data from local storage
const userPreferences = JSON.parse(localStorage.getItem('user_preferences'));
- Implement a fallback mechanism for browsers with stricter limits
Example: Fallback mechanism for cookie storage
function setCookie(name, value, days) {
try {
document.cookie = `${name}=${value}; max-age=${days * 24 * 60 * 60}; path=/`;
} catch (error) {
console.warn(`Failed to set cookie: ${error.message}`);
localStorage.setItem(name, value);
}
}
function getCookie(name) {
const value = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)');
return value ? value.pop() : localStorage.getItem(name);
}
Handling International Characters
When dealing with international characters in cookies, consider these approaches:
- Use
encodeURIComponent()
for encoding anddecodeURIComponent()
for decoding - For more complex scenarios, use
btoa()
andatob()
for Base64 encoding
Example: Handling international characters in cookies
// Encoding international characters
const internationalName = "안녕하세요";
document.cookie = `greeting=${encodeURIComponent(internationalName)}; path=/`;
// Decoding
const storedGreeting = decodeURIComponent(getCookie('greeting'));
// Base64 encoding for complex data
const complexData = { name: "José", age: 30, city: "São Paulo" };
document.cookie = `userData=${btoa(JSON.stringify(complexData))}; path=/`;
// Decoding Base64
const decodedData = JSON.parse(atob(getCookie('userData')));
Cookie Attribute Considerations
Domain Attribute and Character Limitations
The domain attribute in cookies defines which hosts can receive the cookie. Here are key points about domain attribute and its character limitations:
Allowed Characters
- Alphanumeric characters (a-z, A-Z, 0-9)
- Hyphens (-)
- Periods (.)
Domain Name Rules
- Must start and end with alphanumeric characters
- Cannot contain consecutive periods
- Maximum length of 253 characters
Subdomain Considerations
- Setting the domain to a specific subdomain limits the cookie to that subdomain
- Using a leading dot (.) allows the cookie to be shared with subdomains
Example: Valid and Invalid Domain Settings
Valid Domain Settings | Invalid Domain Settings |
---|---|
example.com | .example.com (leading dot) |
sub.example.com | example..com (consecutive periods) |
my-site.com | -example.com (starts with hyphen) |
123.example.com | example.com- (ends with hyphen) |
Example: Setting Domain Attribute
// Cookie for specific subdomain
document.cookie = "name=value; domain=subdomain.example.com";
// Cookie shared with all subdomains
document.cookie = "name=value; domain=example.com";
Expire and Max-Age Attributes
The Expire and Max-Age attributes control when a cookie should be deleted.
Expires Attribute
- Uses GMT/UTC time zone
- Format: "Wdy, DD-Mon-YYYY HH:MM:SS GMT"
- Example: "Wed, 21 Oct 2023 07:28:00 GMT"
Max-Age Attribute
- Positive integer representing seconds
- Maximum value depends on browser implementation (typically around 2^31 - 1)
Example: Expires vs Max-Age
Feature | Expires | Max-Age |
---|---|---|
Time reference | Absolute date | Relative to current time |
Format | Date string | Number of seconds |
Browser support | All browsers | Most modern browsers |
Precedence | Lower | Higher (if both set) |
Example: Setting Expiration
// Using Expires attribute
const expirationDate = new Date();
expirationDate.setDate(expirationDate.getDate() + 7);
document.cookie = `name=value; expires=${expirationDate.toUTCString()}`;
// Using Max-Age attribute (7 days in seconds)
document.cookie = "name=value; max-age=604800";
Additional Cookie Attributes
Secure Attribute
- Makes sure cookie is only sent over HTTPS
- Usage:
document.cookie = "name=value; secure";
HttpOnly Attribute
- Prevents access to the cookie through client-side scripts
- Helps reduce cross-site scripting (XSS) attacks
- Usage:
document.cookie = "name=value; HttpOnly";
SameSite Attribute
Controls when cookies are sent with cross-site requests:
- Strict: Only send for same-site requests
- Lax: Send for same-site and top-level navigation from external sites
- None: Allow cross-site sending (requires Secure attribute)
Example: Setting SameSite Attribute
document.cookie = "name=value; SameSite=Strict";