Cookies в JavaScript: создание, чтение и безопасное управление данными
Для кого эта статья:
- Для веб-разработчиков и программистов, интересующихся работой с cookies в JavaScript
- Для студентов и людей, обучающихся веб-разработке, желающих углубить свои знания
Для специалистов по UX и маркетингу, интересующихся влиянием cookies на поведение пользователей
Вы когда-нибудь задумывались, почему интернет-магазин "помнит" товары в вашей корзине даже после закрытия браузера? Или как сайты сохраняют ваш логин, избавляя от необходимости вводить пароль при каждом посещении? Ответ кроется в маленьких, но мощных инструментах веб-разработки — cookies. Эти небольшие фрагменты данных играют колоссальную роль в создании персонализированного опыта пользователей. Давайте погрузимся в мир cookies и научимся мастерски управлять ими с помощью JavaScript. 🍪
Хотите научиться создавать современные веб-приложения с использованием продвинутых технологий, включая работу с cookies и локальным хранилищем? Обучение веб-разработке от Skypro даст вам не только теоретические знания, но и практические навыки работы с JavaScript, которые востребованы на рынке прямо сейчас. Вы научитесь создавать динамические интерфейсы, управлять данными пользователей и обеспечивать безопасное взаимодействие с веб-сервисами — всё это с акцентом на реальные проекты и актуальные технологии.
Cookies в веб-разработке: основы и принципы работы
Cookies (куки) — это небольшие текстовые файлы, которые веб-сервер отправляет браузеру пользователя, а тот, в свою очередь, сохраняет их на устройстве. При последующих запросах к этому серверу браузер автоматически отправляет сохраненные cookies обратно, позволяя серверу "узнать" пользователя.
Технически, cookie — это строка текста, состоящая из пар ключ-значение, которая передаётся между клиентом и сервером в HTTP-заголовках. Когда сервер отправляет страницу браузеру, он может включить директиву Set-Cookie в HTTP-ответ:
Set-Cookie: username=john_doe; expires=Thu, 18 Dec 2023 12:00:00 GMT; path=/
Браузер сохраняет эту информацию и при каждом запросе к данному домену отправляет cookie обратно в заголовке Cookie:
Cookie: username=john_doe
Cookies используются для решения множества задач:
- Управление сессиями — поддержание состояния авторизации пользователя
- Персонализация — сохранение пользовательских настроек
- Отслеживание — анализ поведения пользователей на сайте
- Корзины покупок — сохранение товаров между сессиями
Каждое cookie состоит из нескольких компонентов:
| Компонент | Описание | Обязательный |
|---|---|---|
| Имя | Идентификатор cookie (например, "username") | Да |
| Значение | Хранимые данные (например, "john_doe") | Да |
| Срок действия | Когда cookie должен быть удален | Нет |
| Путь | Для каких URL cookie будет отправляться | Нет |
| Домен | Для каких доменов cookie действителен | Нет |
| Secure | Отправляется только по HTTPS | Нет |
| HttpOnly | Недоступен для JavaScript | Нет |
| SameSite | Ограничивает отправку cookies при кросс-сайтовых запросах | Нет |
Андрей Петров, Senior Frontend Developer
Однажды мы столкнулись с интересной проблемой в нашем e-commerce проекте. Пользователи жаловались, что товары исчезают из корзины, когда они переходят с настольных компьютеров на мобильные устройства. Поначалу мы думали, что проблема в синхронизации данных на сервере, но причина оказалась в неправильной настройке cookies.
Мы хранили состояние корзины в cookie с доменом www.example.com, из-за чего эти данные не были доступны при переходе на мобильную версию m.example.com. Решением стало изменение домена cookie на .example.com, что позволило использовать общие данные для всех поддоменов.
Этот случай хорошо иллюстрирует, насколько важно понимать тонкости работы с cookies, особенно когда речь идет о кросс-доменном взаимодействии. Теперь я всегда сначала тщательно продумываю стратегию хранения данных, учитывая все возможные сценарии использования.

Особенности и ограничения куки в современном JavaScript
В современном мире веб-разработки cookies продолжают играть важную роль, однако они обладают рядом ограничений, которые разработчикам необходимо учитывать. 🔍
Основные ограничения cookies:
- Размер: общее ограничение — 4KB на каждое cookie
- Количество: большинство браузеров ограничивают до 50-100 cookies на домен
- Доменные ограничения: cookie привязаны к конкретному домену и недоступны для других доменов
- HTTP-запросы: cookies отправляются с каждым запросом, что может увеличить объем трафика
- Безопасность: cookies не защищены от XSS-атак без дополнительных мер
Одна из ключевых особенностей cookies — они отправляются с каждым запросом к серверу. Это отличает их от других способов хранения данных в браузере, например, localStorage или sessionStorage, которые никогда не отправляются на сервер.
| Характеристика | Cookies | localStorage | sessionStorage |
|---|---|---|---|
| Срок хранения | Настраиваемый (через expires/max-age) | Постоянно (до ручного удаления) | До закрытия вкладки |
| Лимит данных | ~4KB | ~5MB | ~5MB |
| Отправка на сервер | Автоматически с каждым запросом | Нет | Нет |
| Доступ из JavaScript | Да (кроме HttpOnly cookies) | Да | Да |
| API | Низкоуровневый (document.cookie) | Простой (getItem/setItem) | Простой (getItem/setItem) |
В современном JavaScript работа с cookies выполняется через свойство document.cookie, которое имеет довольно специфический интерфейс. При чтении оно возвращает все доступные cookies в виде одной строки, а при записи позволяет установить только одно cookie за раз:
// Чтение всех cookies (возвращает строку)
console.log(document.cookie); // "name=value; name2=value2"
// Установка cookie (не перезаписывает другие cookies)
document.cookie = "user=John; expires=Thu, 18 Dec 2023 12:00:00 GMT; path=/";
С появлением SPA (Single Page Applications) и PWA (Progressive Web Applications) роль cookies изменилась. Во многих современных приложениях для хранения состояния на клиенте используются localStorage и Redux, а cookies применяются в основном для аутентификации и отслеживания.
Ещё одно важное ограничение — политика SameSite, которая по умолчанию установлена как "Lax" в большинстве современных браузеров. Это означает, что cookies не будут отправляться при переходе с других сайтов, что усложняет реализацию некоторых сценариев интеграции.
Создание и настройка cookies: синтаксис и параметры
Создание cookies в JavaScript выполняется через прямое присваивание строки свойству document.cookie. Несмотря на кажущуюся простоту, этот процесс требует понимания специфического синтаксиса и доступных параметров. 🛠️
Базовый синтаксис создания cookie выглядит так:
document.cookie = "имя=значение; expires=дата; path=путь; domain=домен; secure; samesite=значение";
Рассмотрим основные параметры, которые можно использовать при создании cookies:
- expires — устанавливает дату истечения срока действия cookie (в GMT формате)
- max-age — альтернатива expires, указывает время жизни cookie в секундах
- path — определяет, для каких путей на сервере будет доступен cookie
- domain — указывает, для каких доменов cookie будет доступен
- secure — флаг, указывающий, что cookie должен передаваться только по HTTPS
- samesite — определяет, когда cookie будут отправляться при кросс-сайтовых запросах
- httpOnly — флаг, делающий cookie недоступным для JavaScript (устанавливается только сервером)
Важно понимать, что значения cookie должны быть закодированы с помощью encodeURIComponent() для предотвращения проблем с специальными символами:
// Неправильно
document.cookie = "user=John Doe; path=/";
// Правильно
document.cookie = "user=" + encodeURIComponent("John Doe") + "; path=/";
Давайте рассмотрим примеры создания cookies с различными параметрами:
// Создание cookie с истечением срока через 1 день
let date = new Date();
date.setDate(date.getDate() + 1);
document.cookie = "username=John; expires=" + date.toUTCString() + "; path=/";
// Создание cookie с max-age (30 дней в секундах)
document.cookie = "preferences=darkmode; max-age=2592000; path=/";
// Создание secure cookie (только для HTTPS)
document.cookie = "token=abc123; secure; path=/";
// Создание cookie с SameSite=Strict
document.cookie = "analytics=enabled; samesite=strict; path=/";
Стоит отметить различия между параметрами expires и max-age:
| Параметр | Формат | Преимущества | Недостатки |
|---|---|---|---|
| expires | Конкретная дата в GMT (например, "Thu, 18 Dec 2023 12:00:00 GMT") | Широкая поддержка во всех браузерах | Требует конвертации даты, зависит от системного времени |
| max-age | Количество секунд (например, 86400 для 1 дня) | Проще в использовании, независим от системного времени | Не поддерживается в Internet Explorer до версии 9 |
Для удобства работы с cookies часто создают вспомогательные функции. Вот пример функции, которая упрощает установку cookie:
function setCookie(name, value, options = {}) {
// Устанавливаем значение по умолчанию для path
options = {
path: '/',
// Добавляем другие значения по умолчанию при необходимости
...options
};
// Если указан expires как объект Date, преобразуем его в UTC строку
if (options.expires instanceof Date) {
options.expires = options.expires.toUTCString();
}
// Кодируем значение
let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
// Добавляем параметры в cookie
for (let optionKey in options) {
updatedCookie += "; " + optionKey;
let optionValue = options[optionKey];
if (optionValue !== true) {
updatedCookie += "=" + optionValue;
}
}
// Устанавливаем cookie
document.cookie = updatedCookie;
}
// Использование функции
setCookie('user', 'John', {
'max-age': 3600,
secure: true,
samesite: 'strict'
});
Ирина Соколова, UX-исследователь
Когда я работала над проектом по оптимизации процесса аутентификации пользователей, мы обнаружили удивительную закономерность. Около 40% пользователей отказывались от регистрации, если система не предлагала функцию "запомнить меня". И дело было не только в удобстве!
Анализируя поведение пользователей и проводя интервью, мы выяснили, что многие люди относятся к повторному вводу паролей с подозрением — они считают, что если сайт "забывает" их между сессиями, значит, он ненадежен в целом.
Мы реализовали надежную систему persistent authentication с использованием двух типов cookies: кратковременных сессионных и долгосрочных для функции "запомнить меня". Особенно интересно, что в последнем случае мы не храним пароль, а используем специальный токен с ограниченным сроком действия.
Результаты были впечатляющими — конверсия регистраций выросла на 27%, а уровень повторных посещений увеличился на 18%. Это наглядно показывает, как правильная работа с cookies может напрямую влиять на ключевые бизнес-показатели.
Чтение и модификация cookies с помощью JavaScript
Чтение cookies в JavaScript может показаться простой задачей, но имеет свои нюансы. Свойство document.cookie возвращает все доступные cookies в виде одной строки, где каждая пара имя-значение разделена точкой с запятой и пробелом. 🔍
// Пример значения document.cookie
// "username=John; preferences=darkmode; token=abc123"
Для получения значения конкретного cookie требуется разобрать эту строку. Вот пример функции, которая извлекает значение cookie по его имени:
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
// Использование
const username = getCookie("username");
console.log(username); // "John"
Важно помнить о необходимости декодирования значения с помощью decodeURIComponent(), так как при установке cookie значения кодируются.
Для изменения существующего cookie необходимо установить новое cookie с тем же именем, путем, доменом и другими параметрами:
// Изменение значения cookie "username"
document.cookie = "username=Alex; path=/; max-age=3600";
Если вы не укажете те же параметры (path, domain и т.д.), что были у исходного cookie, браузер создаст новый cookie вместо обновления существующего.
Работа с множеством cookies может стать сложной задачей. Для облегчения управления cookies можно создать объект, который обеспечит удобный интерфейс:
const Cookies = {
// Получить cookie
get: function(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
},
// Установить cookie
set: function(name, value, options = {}) {
options = {
path: '/',
...options
};
if (options.expires instanceof Date) {
options.expires = options.expires.toUTCString();
}
let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
for (let optionKey in options) {
updatedCookie += "; " + optionKey;
let optionValue = options[optionKey];
if (optionValue !== true) {
updatedCookie += "=" + optionValue;
}
}
document.cookie = updatedCookie;
},
// Удалить cookie
delete: function(name) {
this.set(name, "", {
'max-age': -1
});
},
// Получить все cookies как объект
getAll: function() {
let pairs = document.cookie.split("; ");
let cookies = {};
for (let i = 0; i < pairs.length; i++) {
let pair = pairs[i].split("=");
cookies[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || "");
}
return cookies;
}
};
// Примеры использования
Cookies.set("theme", "dark", {"max-age": 86400});
console.log(Cookies.get("theme")); // "dark"
console.log(Cookies.getAll()); // {theme: "dark", username: "John", ...}
Cookies.delete("theme");
При работе с cookies важно помнить о нескольких сценариях, которые могут вызвать проблемы:
- Пустые cookies — если cookie не существует или его значение пустое, функция чтения должна корректно обрабатывать этот случай
- Одинаковые имена cookies — при наличии нескольких cookies с одинаковым именем, но разными путями/доменами, document.cookie возвращает только один из них
- Ограничения доступа — HttpOnly cookies недоступны через JavaScript, что может вызвать путаницу при отладке
При работе с cookies в реальных приложениях часто используются библиотеки, такие как js-cookie, которые упрощают все вышеописанные операции и обрабатывают краевые случаи:
// С библиотекой js-cookie
Cookies.set("user", "John");
Cookies.get("user"); // "John"
Cookies.remove("user");
Удаление cookies и вопросы безопасности при работе с ними
Удаление cookies — важный аспект управления данными пользователя, особенно при выходе из системы или очистке персональных данных. В JavaScript для удаления cookie необходимо установить его с истекшим сроком действия. 🔒
Существует два основных способа удаления cookie:
// Способ 1: установка даты истечения в прошлом
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
// Способ 2: использование max-age с отрицательным значением
document.cookie = "username=; max-age=-1; path=/";
Критически важно указать тот же путь (и домен, если он был установлен), что и при создании cookie. В противном случае браузер не сможет найти и удалить нужное cookie.
Функция для удаления cookie может выглядеть так:
function deleteCookie(name, options = {}) {
options = {
path: '/',
...options
};
// Устанавливаем срок действия в прошлом
document.cookie = encodeURIComponent(name) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
// Добавляем все дополнительные параметры
for (let optionKey in options) {
document.cookie += "; " + optionKey;
let optionValue = options[optionKey];
if (optionValue !== true) {
document.cookie += "=" + optionValue;
}
}
}
// Использование
deleteCookie("username", {domain: ".example.com"});
Теперь рассмотрим вопросы безопасности при работе с cookies, которые являются критически важными для защиты пользовательских данных:
| Уязвимость | Описание | Меры защиты |
|---|---|---|
| XSS (Cross-Site Scripting) | Атакующий может внедрить вредоносный скрипт, который получит доступ к cookies | Использование флага HttpOnly, валидация всех пользовательских входных данных |
| CSRF (Cross-Site Request Forgery) | Злоумышленник заставляет пользователя выполнить действие на сайте, где он аутентифицирован | Использование SameSite=Strict/Lax, CSRF-токенов |
| Cookie Theft | Перехват cookies при передаче по незащищенному соединению | Использование флага Secure, HTTPS |
| Session Fixation | Атакующий устанавливает известный ему идентификатор сессии | Регенерация ID сессии при аутентификации |
| Cookie Tossing | Установка поддоменных cookies для перезаписи других cookies | Использование __Host- префикса, точное указание домена |
Основные рекомендации по безопасной работе с cookies:
- Используйте HttpOnly для cookies, содержащих чувствительные данные, чтобы предотвратить доступ через JavaScript
- Включайте флаг Secure для отправки cookies только по HTTPS
- Применяйте SameSite=Strict для cookies аутентификации, чтобы предотвратить CSRF-атаки
- Устанавливайте минимально необходимый срок действия cookies
- Используйте минимально необходимый path для ограничения области действия cookie
- Не храните конфиденциальную информацию в cookies напрямую
- Используйте префикс __Host- для критически важных cookies (например, _Host-sessionid)
Примеры безопасной установки cookies:
// Безопасный cookie для аутентификации
document.cookie = "__Host-session=abc123; path=/; secure; samesite=strict";
// Cookie для аналитики, доступный JavaScript'у
document.cookie = "analytics_id=xyz789; path=/; secure; samesite=lax; max-age=2592000";
// Cookie для API, защищенный от XSS
// (HttpOnly может быть установлен только сервером)
// Set-Cookie: api_token=token123; path=/api; secure; httponly; samesite=strict
С появлением более строгих политик приватности и регуляций вроде GDPR и CCPA, важно предоставлять пользователям возможность управлять cookies. Это часто реализуется через "Cookie Consent Banners", которые позволяют принимать или отклонять различные типы cookies:
function acceptAllCookies() {
// Установка необходимых cookies
Cookies.set("necessary", "true", {expires: 365});
// Установка аналитических cookies
Cookies.set("analytics", "true", {expires: 365});
// Установка маркетинговых cookies
Cookies.set("marketing", "true", {expires: 365});
// Сохранение выбора пользователя
Cookies.set("cookie_consent", "accepted_all", {expires: 365});
// Скрытие баннера согласия
document.getElementById("cookie-banner").style.display = "none";
}
function acceptNecessaryCookies() {
// Установка только необходимых cookies
Cookies.set("necessary", "true", {expires: 365});
// Сохранение выбора пользователя
Cookies.set("cookie_consent", "accepted_necessary", {expires: 365});
// Удаление не-необходимых cookies
Cookies.remove("analytics");
Cookies.remove("marketing");
// Скрытие баннера согласия
document.getElementById("cookie-banner").style.display = "none";
}
Cookies остаются неотъемлемой частью современной веб-разработки, несмотря на появление альтернативных способов хранения данных. Понимание их структуры, особенностей и правил безопасной работы позволяет создавать более надежные и персонализированные веб-приложения. Независимо от того, используете ли вы cookies для управления сессиями, сохранения пользовательских настроек или аналитики, правильный подход к их реализации поможет улучшить как пользовательский опыт, так и безопасность вашего приложения. Помните о балансе между функциональностью и приватностью — и ваши cookies будут приносить пользу, а не проблемы.