Cookie — один из способов хранить данные в браузере. Обзор всех способов хранения описан в статье «Хранение данных в браузере».
Кратко
СкопированоПри разработке сайтов часть информации (например, токен авторизации или данные пользователя) нужно хранить и читать как в браузере, так и на сервере. Для этого используют Cookie (произносится «куки»).
Как пользоваться
СкопированоВсе куки хранятся в свойстве document
. Это свойство представляет собой строку в формате имя
, где пары имён и значений разделяются знаком ;
. При этом взаимодействие с полем весьма необычное — если присвоить document
новое значение, то оно не заменит полностью старую строку, а добавит или изменит значение по ключу.
Запись
СкопированоЗапись в cookie работает с помощью присвоения значения новой куки в поле document
. За один раз можно записать лишь одно значение.
Вот так можно добавить значение 1 по ключу counter:
document.cookie = 'counter=1'console.log(document.cookie)// 'counter=1'
document.cookie = 'counter=1' console.log(document.cookie) // 'counter=1'
При присвоении свойству куки с другим именем, получим два записанных значения:
document.cookie = 'sidebar=false'console.log(document.cookie)// 'counter=1; sidebar=false;'
document.cookie = 'sidebar=false' console.log(document.cookie) // 'counter=1; sidebar=false;'
При повторной записи в то же поле другого значения оно будет перезаписано.
document.cookie = 'sidebar=true'console.log(document.cookie)// -> 'counter=1; sidebar=true;'
document.cookie = 'sidebar=true' console.log(document.cookie) // -> 'counter=1; sidebar=true;'
При установке кук можно указывать не только её название и значение, но и другие параметры. Все они являются необязательными и разделяются точкой с запятой ;
.
path
— определяет путь, по которому будет доступна кука. Он должен быть абсолютным, то есть начинаться с/
. Если параметр не передан, то кука будет доступна на всех страницах сайта.domain
— определяет домен, для которого указана кука. Если не указано, то будет использоваться текущий домен.max
и- age expires
— определяет время жизни куки.max
указывает, через сколько секунд, а- age expires
указывает точное время, когда кука станет недействительна. Время дляexpires
можно отформатировать с помощью встроенного метода датыDate . toUTC String ( ) secure
— указывает, что данная кука может быть передана только при запросах по защищённому протоколу HTTPS.samesite
— определяет, может ли данная кука быть отправлена при кроссдоменном запросе. Значение параметраstrict
будет предотвращать отправку на другие домены, аlax
разрешит отправлять куки с GET-запросами.
Есть пара ограничений при специфичных названиях кук. Если название куки начинается с _
, то обязательно должен быть передан параметр secure
. При этом мы должны находиться на странице, которая была получена по HTTPS-протоколу. Если название куки начинается с _
, то обязательно должны быть переданы параметры path
и secure
(страница также должна быть открыта по HTTPS-протоколу), а атрибут domain
должен отсутствовать для снижения кроссдоменных уязвимостей.
Запись куки с разрешением передавать её только по HTTPS и только для текущего домена, со временем жизни в 1 час будет выглядеть так:
document.cookie = 'sidebar=true;secure;samesite=strict;max-age=3600'
document.cookie = 'sidebar=true;secure;samesite=strict;max-age=3600'
Чтение
СкопированоДля получения значений, записанных в куки, можно просто вывести содержимое document
:
console.log(document.cookie)
console.log(document.cookie)
Учитывая, что мы уже дважды записывали куки, при вызове команды выше в консоли выведется counter
.
Чтобы получить значение конкретной куки, нам нужно будет прочитать строки и разобрать её по значениям. Например, так:
function getCookie() { return document.cookie.split('; ').reduce((acc, item) => { const [name, value] = item.split('=') acc[name] = value return acc }, {})}const cookie = getCookie()console.log(cookie.counter)// 1console.log(cookie.sidebar)// true
function getCookie() { return document.cookie.split('; ').reduce((acc, item) => { const [name, value] = item.split('=') acc[name] = value return acc }, {}) } const cookie = getCookie() console.log(cookie.counter) // 1 console.log(cookie.sidebar) // true
Удаление
СкопированоДля кук не предусмотрено специального метода удаления, поэтому для этого используется трюк с установкой кук с параметром expires
который указывает на дату в прошлом. Браузер сразу же считает такую куку устаревшей и удаляет её:
document.cookie = `sidebar=;expires=${new Date(0)}`
document.cookie = `sidebar=;expires=${new Date(0)}`
В этом примере, передав число 0 в конструктор Date
мы получаем время на начало эпохи Unix, а именно 1 января 1970 года. Поскольку эта дата из прошлого, то кука будет удалена моментально.
На практике
Скопированосоветует Скопировано
🛠 Есть куки, которые нельзя прочитать или записать из JavaScript. Если сервер устанавливает куки с параметром Http
(доступен только для установки сервером), то такие куки будут недоступны в document
. Как правило, такие куки используются для хранения чувствительной информации, как, например, токены для авторизации. Проверка авторизации происходит с помощью запроса с текущим авторизованным пользователем и считается при успешном ответе сервера.
советует Скопировано
🛠 Формат строки document
не очень удобен для работы, поэтому обычно в проекте создают функции, которые упрощают чтение и запись кук. Чтобы не писать эти функции самостоятельно, можно взять библиотеку js-cookie. Это небольшая обёртка над стандартным браузерным API, которая здорово упрощает жизнь.
С этой библиотекой установка значения для куки выполняется так:
import Cookies from "js-cookie"Cookies.set("foo", "bar")
import Cookies from "js-cookie" Cookies.set("foo", "bar")
А чтение так:
import Cookies from "js-cookie"const nameFromCookie = Cookies.get("name")
import Cookies from "js-cookie" const nameFromCookie = Cookies.get("name")
Конечно, под капотом эта библиотека тоже работает с document
, но снаружи она предоставляет простой и удобный интерфейс.