Работа с куки на чистом JavaScript без головной боли

Привет, Хабр!


Недавно я столкнулся с необходимостью работать с куки-файлами при помощи JavaScript. Когда я увидел, насколько ужасна работа с document.cookie на чистом JavaScript, я полез искать библиотеку для удобства работы с куками. Как оказалось, немногие библиотеки для работы с куками, хоть и на первый взгляд кажутся простыми и удобными, в процессе работы с ними обнаруживаеся немало подводных камней. Вот некоторые из них:


  • Получение куки по указанному пути — некоторые из испробованных библиотек имели проблемы с доступом к куки с указанием пути: например, со страницы сайта я не мог получить куки с путём / или наоборот, находясь в "корне" сайта через раз получал undefined при попытке получить куки по указанному пути /order
  • Поддержка JSON — встречается, но работает криво: например, при получении куки, хранящего JSON, вы получите URI-encoded строку, которую должны будете сами раскодировать и распарсить. Подключать библиотеку в свой код и дописывать функции для решения этой проблемы как-то неправильно.
  • Удаление куки — у всех библиотек были проблемы с удалением кук. Практически все чистили значение куки, но не удаляли его. Отдельные проблемы были с сессионными куки: некоторые библиотеки не видели их в "упор", и ни одна из них не смогла удалить сессионные куки.
    Не стану называть билиотеки, которые я попробовал, так как не считаю это корректным по отношению к их разработчикам, но уточню, что пробовал самые попуярные библиотеки (по версии npm) для работы с куки.

Последняя проблема уже окончательно взбесила меня, и я решил, что пора написать собственную библиотеку для работы с куки.


Cookie.js (npm — cookielib)


Данная библиотека решила все вышеперечисленные проблемы, сохранив небольшие размеры своих предшественников и удобство использования функций.


Почему следует использовать её?


  • Решила все проблемы, описанные выше, сохранив свои размеры и простоту в использовании.
  • Минифицированная версия — всего 707 байт
  • Не основывается на классе-обработчике, что экономит время и ресурсы
  • Работает с JSON "из коробки" (Возвращает объект JSON, если программист ожидает его получить, может создавать JSON-куки, приняв в качестве парамера JSON-объект)
  • При создании куки можно задать любые куки-свойства
  • Работает со всеми браузерами (Даже ES6!)
  • Написана на чистом JS (Никаких зависимостей)
  • Может быть установлена при помощи npm, доступна по CDN, может быть легко интегрирована с использованием исходного кода библиотеки

Немного о работе с библиотекой


Создать сессионное куки:


setCookie('name', 'value');  // строчный куки
setCookie('name', {'key': 'value'});  // json куки

Создать "истекающее" куки:


setCookie('name', 'value', {expires: Date(3)});  // строка с параметром
setCookie('name', {'key': 'value'}, {expires: Date(3)});  // json с параметром

С функцией setCookie() можно задать любые параметры куки. Параметры можно найти ниже.


Получить куки:


getCookie('name')  // получить строку
getCookie('name', json=true)  // получить куки json, если куки является json. Возвращает объект JSON

Удаление куки:


deleteCookie('name');  // json или строка - не важно!

Параметры куки


Для задания параметра куки, вызовите функцию setCookie(name, value, dict), заполнив dict параметр как словарь "параметр куки": "значение параметра"


Список ключей-значений:


  • path (str) — URL, по котрому доступен куки
  • domain (str) — домен, для котрого куки доступен
  • expires (Date object) — время "истечения" куки (дата/время задаются как Date-объект)
  • max-age (int) — время жизни куки в секундах (альтернатива параметру expires)
  • secure (bool) — если true, куки будет доступен по HTTPS. НЕ МОЖЕТ БЫТЬ false
  • samesite (str) — настройка, необходимая для защиты от XSRF-атак… Может принимать значения strict или lax. Ознакомьтесь с этой статьёй, если хотите узнать больше о подобных атаках и предназначении данного параметра.
    • httpOnly (bool) — если true, куки не будет доступен для работы с ним при помощи JavaScript. НЕ МОЖЕТ БЫТЬ false

Заключение


Данная библиотека была создана с целью исправить все недочёты ее аналогов, которые смело можно назвать полурабочими. Ссылка на GitHub. Хочу услышать комментарии сообщества.


Примечания


Выпустил новую версию, учитывая замечания printf и RekGRpth. Спасибо за замечания!

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 7

    +3
    зря, наверно, два раза вызываете
    .replace(/(?!^)'(?!$)/g, '"')
    и
    JSON.parse
      0
      согласен с вами: это нерационально. Я исправлю это в ближайшее время. Спасибо!
      +2
      А зачем заменять кавычки? В стандарте JSON только двойные, наверное лучше оставить двойные.

      Замена приводит вот к такому багу:
      setCookie('a', { company: "O'Reilly Media, Inc." })
      const a = getCookie('a', true)
      typeof(a) // 'string', а я так хотел JSON...
      
        0
        Спасибо, вы подметили важный баг. Я обязательно исправлю его и отмечу вас в публикации
        +3

        Где тесты?

          0
          Тестов нет, возможно, появятся в ближайших релизах. Прошу открыть issue на GitHub.
          0

          В общем, как бы то ни было, но вот ссылка на статью Ильи Кантора, где живет этот код (тут)


          Ну и, как не крути, есть cookie пакет, который как минимум 17 миллионов раз в неделю скачивается. Хорошо протестирован и максимально безопасен.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое