Свойство document.cookie
Взглянем на классический способ работы с куки. Соответствующая спецификация существует, благодаря Netscape, с 1994 года. Компания Netscape реализовала свойство document.cookie в Netscape Navigator в 1996 году. Вот определение куки из тех времён:
Куки — это небольшой фрагмент информации, хранящийся на клиентской машине в файле cookies.txt.
Главу про document.cookie даже можно найти во втором издании книги «Javascript. The Definitive Guide», которое вышло в январе 1997 года. Это было 24 года тому назад. И мы всё ещё пользуемся тем же старым способом работы с куки ради обратной совместимости.
Как же это выглядит?
Получение куки
const cookies = document.cookie; // возвращает "_octo=GH1.1.123.456; tz=Europe%2FMinsk" on GitHub
Да, именно так всё и делается. В нашем распоряжении оказывается строка со всеми значениями, хранящимися в куки-файле, разделёнными точкой с запятой.
Как вытащить из этой строки отдельное значение? Если вам кажется, что для этого надо самостоятельно разбить строку на части — знайте, что так оно и есть:
function getCookieValue(name) { const cookies = document.cookie.split(';'); const res = cookies.find(c => c.startsWith(name + '=')); if (res) { return res.substring(res.indexOf('=') + 1); } }
Как узнать о том, когда истекает срок действия какого-нибудь из куки? Да, в общем-то, никак.
А как узнать домен, с которого установлен какой-нибудь куки? Тоже никак.
Правда, если надо, можно распарсить HTTP-заголовок Cookie.
Установка куки
document.cookie = 'theme=dark';
Вышеприведённая команда позволяет создать куки с именем theme, значением которого является dark. Хорошо. Значит ли это, что document.cookie — это строка. Нет, не значит. Это — сеттер.
document.cookie = 'mozilla=netscape';
Эта команда не перезапишет куки с именем theme. Она создаст новый куки с именем mozilla. Теперь у нас имеются два куки.
По умолчанию срок действия куки, созданного так, как показано выше, истекает после закрытия браузера. Но при создании куки можно указать срок его действия:
document.cookie = 'browser=ie11; expires=Tue, 17 Aug 2021 00:00:00 GMT';
Да. Это — как раз то, что мне нужно — подбирать дату и время истечения срока действия куки в формате GMT каждый раз, когда нужно установить куки. Ладно, давайте воспользуемся для решения этой задачи JavaScript-кодом:
const date = new Date(); date.setTime(date.getTime() + (30 * 24 * 60 * 60 * 1000)); // здорово-то как document.cookie = `login=mefody; expires=${date.toUTCString()}; path=/`;
Но, к счастью, у нас есть и другой способ установки момента истечения срока действия куки:
document.cookie = 'element=caesium; max-age=952001689';
Свойство max-age представляет собой срок «жизни» куки в секундах. Соответствующее значение имеет более высокий приоритет, чем то, которое задано с помощью свойства expires.
И не надо забывать о свойствах path и domain. По умолчанию куки устанавливаются для текущего расположения и текущего хоста. Если надо установить куки для всего домена — надо будет добавить к команде установки куки конструкцию такого вида:
; path=/; domain=example.com
Удаление куки
document.cookie = 'login=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
Для удаления куки надо установить дату и время истечения срока действия куки на какой-нибудь момент из прошлого. Для того чтобы всё точно сработало бы — тут рекомендуется использовать начало эпохи Unix.
Работа с куки в сервис-воркерах
Это просто невозможно. Дело в том, что работа с document.cookie — это синхронная операция, в результате воспользоваться ей в сервис-воркере нельзя.
Cookie Store API
Существует черновик стандарта одного замечательно API, направленного на работу с куки, который способен значительно облегчить нам жизнь в будущем.
Во-первых — это асинхронный API, а значит — пользоваться им можно, не блокируя главный поток. Применять его можно и в сервис-воркерах.
Во-вторых — этот API устроен гораздо понятнее, чем существующий механизм работы с куки.
▍Получение куки
const cookies = await cookieStore.getAll(); const sessionCookies = await cookieStore.getAll({ name: 'session_', matchType: 'starts-with', });
Метод getAll возвращает массив, а не строку. Именно этого я и жду, когда пытаюсь получить некий список.
const ga = await cookieStore.get('_ga'); /** { "domain": "mozilla.org", "expires": 1682945254000, "name": "_ga", "path": "/", "sameSite": "lax", "secure": false, "value": "GA1.2.891784426.1616320570" } */
А вот — приятная неожиданность. Можно узнать и дату истечения срока действия куки, и сведения о домене и пути, и при этом не пользоваться никакими хаками.
▍Установка куки
await cookieStore.set('name', 'value');
Или так:
await cookieStore.set({ name: 'name', value: 'value', expires: Date.now() + 86400, domain: self.location.host, path: '/', secure: self.location.protocol === 'https:', httpOnly: false, });
Мне очень нравится этот синтаксис!
▍Удаление куки
await cookieStore.delete('ie6');
Или можно, как раньше, установить дату истечения срока действия куки на некий момент в прошлом, но не вижу причины поступать именно так.
▍События куки
cookieStore.addEventListener('change', (event) => { for (const cookie in event.changed) { console.log(`Cookie ${cookie.name} changed to ${cookie.value}`); } });
Как видите, теперь у нас есть возможность подписываться на изменения куки, не занимаясь опросом document.cookie, блокирующим главный поток. Фантастика!
▍Сервис-воркеры
// service-worker.js await self.registration.cookies.subscribe([ { name: 'cookie-name', url: '/path-to-track', } ]); self.addEventListener('cookiechange', (event) => { // обработка изменений });
Можно ли пользоваться этим API прямо сейчас?
Хотя этим API уже можно пользоваться, но тут надо проявлять осторожность. Cookie Store API работоспособно в Chrome 87+ (Edge 87+, Opera 73+). В других браузерах можно воспользоваться полифиллом, который, правда, не возвращает полной информации о куки, как это сделано в настоящем API. Прогрессивные улучшения — это вещь.
И учитывайте, что спецификация этого API всё ещё находится в статусе «Draft Community Group Report». Но если в вашем проекте важен хороший «опыт разработчика» — попробуйте современный способ работы с куки.
Пробовали ли вы работать с куки по-новому?
ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/556742/



Добавить комментарий