Библиотека для работы с cookies (tasty-cookies)

История старая, я так думаю, все помнят window.cookie = '...' (а может кто этим пользуется), жутко неудобная штука.

Приведу пример на нативном js:

// Добавление печенья
function setCookie(key, value) {
  window.cookie = key + '=' + encodeURIComponent(JSON.stringify(value));
}

// Получение печенья
function getCookie(key) {
  var matches = document.cookie.match(new RegExp(
    '(?:^|; )' + key.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + '=([^;]*)'
  ));
  return JSON.parse(decodeURIComponent(matches[1]));
}

// Добавляем строку
setCookie('string', 'Моя строка');
// Добавляю объект
setCookie('object', {a: 1, b: 2});

// Получаю объект
var object = getCookie('object');


Давным-давно в закаулках сети я нашёл такую замечательнуюи вещь как jQuery cookie, но со временем я стал осознавать, что одного метода мне уже не хватает для удобной работы с печеньем.

Тот же пример с jQuery cookie:

// Добавляем строку
$.cookie('string', 'Моя строка');
// Добавляю объект
$.cookie('object', {a: 1, b: 2});

// Получаю объект
var object = $.cookie('object');

Совсем не давно я стал знакомиться с angular, и как не странно у них тоже своя реализация cookies, не много лучше, но мне она кажется немного «странной», «мудрёной». Методы putObject, getObject — вообще ужас, и зачем они?

И опять пример:

angular.module('cookiesExample', ['ngCookies'])
.controller('ExampleController', ['$cookies', function($cookies) {
  // Добавляем строку
  $cookies.put('string', 'Моя строка');
  // Добавляю объект
  $cookies.putObject('object', {a: 1, b: 2});

  // Получаю объект
  var object = $cookies.getObject('object');
}]);

Мне надоело это разнообразие красок, хотелось бы чего нибудь одного такого теплого, уютного что бы выполняло самые простые вещи и давало отличные инструменты для работы с cookie. Я ушёл глубоко в поиск и к моему удивлению я не чего подходящего мне не нашёл, в не которые библиотеках не хватало методов, в других методов достаточно но они странные для меня. Может я слишком придирчив?

На почве этого всего я решил изобрести свой велосипед с максимально круглыми колёсами и удобным сидением. Мне кажется это правильно. Работа затянулась на несколько суток, в общем вот что получилось сама библиотека tasty-cookies ну и русская документация.

Пример работы tasty-cookies:

Cookie.set({
  // Добавляем строку
  string: 'Моя строка',
  // Добавляю объект
  object: {a: 1, b: 2}
});

// Получаю объект
var object = Cookie.get('object');

Она использует объект JSON поэтому если надо поддержка старых браузеров можно подтянуть грабли типо JSON 3, хотя, о чем это я?

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

Похожие публикации

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

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

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

    +9
    Эм… в свете того факта, что повсеместно насаждается идея server-only кук, а для хранения локальной информации, лучше всё-таки использовать, (простите за тавтологию) Local Storage, хочется лишь добавить картинку с тролейбусом… но лень искать ссылку.
      +2
      Web Storage API Плохо телефонами поддерживается, а opera mini так вообще не знает что это такое а только она занимает 30% доли рынка. Это подходит для конкретного проекта и задачи. Пока к сожалению этим нельзя полностью заменить cookies.

      Как быть если проект заточен под телефоны?

      Я считаю что должны быть инструменты на все случаи жизни, и с разноцветными ручками. Выбирай какой хочешь, каждый для своей цели.
        +1
        по словам caniuse, оперой пользуются ~5%

        image
          +2
          Ну тоже ведь люди.

          Думаю реализовать возможность выбора метода сохранения печенья, там LocalStorage, SessionStorage и Cookie, ну для первых это получиться просто синтаксическая обёртка позволяющая добавлять и получать данные массивами.

          К примеру:
          // Ставим 4 печенек
          Cookie.set({
            a: 1,
            b: 2,
            c: 3,
            d: 4
          });
          
          // Получаем две печеньки
          Cookie.get('a', 'b'); // -> {a: 1, b: 2}
          
          // Удаляю три печеньки
          Cookie.remove('a', 'b', 'c');
          
            +1
            Тогда лучше перестать называть это Cookie, потому что это вводит людей в заблуждение. Например, человек сохраняет информацию через обертку называемую Cookie, смотрит в отладочную консоль на куки — а там пусто.
              0
              Сделаю объект, и создам три экземпляра Cookie, Local и Session. И тут из названия думаю понятно что и где хранит данные.
                0
                Лучше создать обертку под названием ClientStorage, в настройках которой можно указать в какие хранилища можно дублировать информацию.
                Это не самый лучший пример программирования, но все же
                ClientStorage.setup({
                useCookies: true,
                useLocalStorage: true,
                useSession: true
                });
                ClientStorage.set({
                  a: 1,
                  b: 2,
                  c: 3,
                  d: 4
                });
                ClientStorage.get('a', 'b'); // -> {a: 1, b: 2}
                ClientStorage.remove('a', 'b', 'c');
                


                Все зависит от задачи. Получается, я привел пример устойчивого хранилища данных на клиенте. Что то вроде evercookie. Если у вас задача: просто сделать себе удобно — то вы уже справились и можете дальше не заморачиваться.
                  0
                  A еще можно использовать какой-нибудь polyfill.

                  P.S. Кстати, это я слоупок или Markdown для комментариев появился только что?
        0
        Мне в проекте нужны именно куки для хранения данных, которые должны автоматически удалиться через определенное время и localStorage мне, ну, никак в этом не поможет.
          0
          ага, поэтому зачем нам проверять чё мы там храним, давайте посылать всё г**но на сервер.
          Метку времени к записываемым данным добавить сложно что-ли? Куки всёравно удаляются только тогда когда происходит их запрос. Так же поступать и с LS.
            –2
            Для не особо понятливых: еще раз прочтите мой комментарий и обратите внимание на слово автоматически.
              0
              О боги! Сложность написания автоматического удаления данных просто бесконечно велика!
                –2
                Да, вы должно быть шутите!? Давайте еще раз АВТОМАТИЧЕСКИ! Подумайте, а потом я объясню, что означает это слово, если и в этот раз не прокатит.
                  –1
                  Тогда замените слово АВТОМАТИЧЕСКИ на НО МНЕ ЛЕНЬ ПИСАТЬ КОД, так как написанная Вами чистилка кукисов по времени будет тоже автоматизацией. Не автоматически это когда заходишь и ручками начинаешь удалять.
                    –1
                    Это не мне лень писать код, это вам лень думать!
                    Если выключить скрипты, то данные из LS не удалятся. Если же вы поместите данные в cookie, то они удалятся даже с выключенными скриптами, т. е. автоматически. И да, без необходимости писать дополнительный код.
                      0
                      т.е вы храните данные в куках, которые использует сервер для бизнес-логики? Да вы должно быть шутите.
                      Тут два варианта — либо сообщение не имеет ничего общего с библиотекой для работы с куки, либо данные и не появятся в куках из-за выключенного JS.
                      PS куки никуда не денутся пока браузер не попытается их отправить. Я, конечно, могу ошибаться но ВСЕ манипуляции с куками происходят ИСКЛЮЧИТЕЛЬНО при запросах на сервер в домене. Браузер не будет перепроверять 100500 кук каждый раз когда запускается.
                        0

                        В данном случае не имеет значения, что хранится в куках, важно, что данные удаляются по истечению таймера и становятся не доступными вне зависимости от того включен JS или нет в момент загрузки страницы.

                          +1
                          Данные в куках не удалятся если, например, не запускать браузер. Напишите куку с экспайром в 1970 году, закройте браузер и зайдите в папку с куками. Ваши данные будут там.
                          Если выключен JS — данных по сути нет. Включён JS — удалится по метке времени.

                          Преимуществ у куки по сравнению с LS нет, особенно в сфере хранения ДАННЫХ. Нормальные приложения хранят в куках идентификаторы, а данные — на сервере. И вот на сервере уже точно можно следить за удалением данных.

                          Единственный минус решения на LS очень прост — нужно будет написать буквально с десяток строчек кода сверху кода гетеров/сетеров/добавляторов(и заметьте, не надо никаких либ)

                          Зато плюсов от нормального решения на localStorage — мильён.
                            –1

                            Что-то туговато идет. Выделяю жирным данные удаляются и в момент загрузки страницы. При чем тут папка с куками, когда я говорю про момент загрузки страницы!? Это и ребенку понятно что куки будут лежать в папке.


                            Короче, когда мне понадобится решение с LS, я буду использовать LS. Вы же мне пытаетесь впарить кейс, который мне не нужен. А нужно было то, что я уже описал выше. Как и для чего я это использую – флейм за рамками дискуссии.


                            Всего доброго.

        –1
        Печенье! Печенье, Карл!..
          +2
          А вот я вас поддержу. Хотя и редко куки на клиенте нужны, но все же, спасибо, у вас поудобнее чем аналоги (Ангуляр вообще ужасно все реализовал, как ни странно)

          Только один вопрос, зачем, ну зачем вам интеграция с jQuery? ))) Я понимаю, что это две с половиной строки, но просто… зачем?)) Ведь не будет никакой совсем разницы, что с ним, что без него.

          А за пакет в npm отдельное спасибо, привык уже все через него ставить.
            –1
            ну зачем вам интеграция с jQuery
            Просто как синтаксическая обёртка. Где то подсмотрел, наверное все таки излишнее.
              +1
              Лучше наверное убрать. Создает впечатление зависимости от jQuery.
                –1
                Сейчас так и сделаю.
            +9
            Как на меня — вы опоздали с этой либой лет на 15. Оно уже было в MooTools, dojo, atomjs и так далее. Я уж молчу про кучи независимых маленьких библиотечек и плагинов для всяких undescore. И это годы назад.
              +1
              А так же куча библиотек, которые поддерживают множественные варианты для хранения, выбирая лучшее из доступного.
              0
              Если я не ошибаюсь, то в IE будет работать неверно. Если у Вас есть домен example.com и sub.example.com, Вы создаете на каждом домене по куке my_cookie с разными значениями без указания домена (https://tools.ietf.org/html/rfc6265#section-4.1.2.3), т.е. кука не будет проваливаться на сабдомены. Но IE не совсем нормальный браузер. Он отдаст обе куки для сабдомена и когда Вы будете брать первое совпадение по регулярке — будете получать куку с example.com, а не с sub.example.com, как ожидалось, потому что:

              «Q3: If I don’t specify a DOMAIN attribute when a cookie, IE sends it to all nested subdomains anyway?

              A: Yes, a cookie set on example.com will be sent to sub2.sub1.example.com.

              Internet Explorer differs from other browsers in this regard. Here’s a test case (http://debugtheweb.com/test/cookieinherit.aspx)»
                0
                Да действительно так. Надо добавить проверку домена.
                  0
                  Проверка домена не прокатит, так как на уровне js (как и на сервере, в принципе) невозможно получить атрибут domain куки. Или я чего-то не знаю и есть какой-то способ (не мастер js, если честно)?
                –2
                Веселье начнется, когда неймспейс Cookie от tasty-cookies пересечётся с неймспеском Cookie от другой библиотеки :)
                  +1
                  А что вы предлагаете? Кто вообще две библиотеки для одного и того же подключает?
                    0
                    > Кто вообще две библиотеки для одного и того же подключает?
                    первый разработчик сделает крутую библиотеку А использовав tasty-cookies,
                    второй разработчик сделает крутую библиотеку Б использовав другую Cookie-библиотеку с таким же именем Cookie.
                    третий – захочет одновременно использовать А и Б и получит конфликт.

                    Классический пример – Array.prototype.select или forEach во времена, когда jquery был еще не в ходу, а подобие лямбда выражениям в JS уже хотелось. Кажется, каждый пилил свою реализацию, а уже в производных библиотеках происходили конфликты. Сам с этим сталкивался, это очень больно.

                    > А что вы предлагаете?
                    Лично я бы хранил эти функции внутри фреймворка без глобального объекта. А если бы очень хотелось глобальный объект, то, хотя бы, назвал бы его по другому, исключив банальные конфликты с именами кучи уже сделанных решений Cookie / Cookies.

                      0
                      По поводу перового говорить не буду, покажу пример:
                      <script src="path/tasty-cookies.js"></script>
                      <script src="path/library-a.js"></script>
                      <script>
                      var tastyCookies = Cookie;
                      delete Cookie;
                      </script>
                      <script src="path/cookies2.js"></script>
                      <script src="path/library-b.js"></script>
                      

                      Хотя с такой не согласованностью разработчиков, конкретная фигня получается. Эдакий сниппет стайл. Не советую так делать.

                      Вам вообще известно что такое модули? Модульный подход эти проблемы решает на раз два.
                      Пример 2:
                      // libaryA.js
                      exports.libaryA = (function (){
                         var cookies = require('tasty-cookies');
                      }());
                      
                      // libaryB.js
                      exports.libaryB = (function (){
                         var cookies = require('cookies2');
                      }());
                      
                      // core.js
                      exports.core= (function (){
                         var libraryA = require('libraryA');
                         var libraryB = require('libraryB');
                      }());
                      

                      Я здесь не вижу проблем. А чтобы это юзать в браузере придан давно browserify.

                      Классический пример
                      Классический пример плохого js. Кто же стандартные объекты трогает, здесь глюков не избежать. Уже давно придуманы классы, пространства имён и модули.

                      По поводу третьего, я могу подтянуть 5 фреймворков засоряющих одно пространство имён. И как тут быть?
                        0
                        Извиняюсь не правильно прописал подключение tasty-cookies. Не могу редактировать, кому интересно можно посмотреть здесь как правильно подключается github.com/Alex5646/cookie.js#use-in-commonjsnode
                          0
                          Вместо попыток меня уделать, попробуйте понять суть проблемы :)

                          Но раз уж дошло до срача, и вы просили критики в статье, вот вам критика:

                          1. во первых вы хреново прогуглилили github.com/js-cookie/js-cookie (с 2009 года)
                          На вскидку – 1 в 1 с вашим велосипедом. Они, кстати, подумали о возможном конфликте неймспейсов, лохи, модулями то не умеют пользоваться :)

                          2. Вот 302 репозитория на эту или похожую тему
                          github.com/search?l=JavaScript&q=js+cookie&type=Repositories&utf8=%E2%9C%93
                          уже на второй странице некий jonlabelle использует такой же неймспейс github.com/jonlabelle/cookie-js
                          и кажется делает все то же самое, но наверняка есть нюансы.
                          Одному Богу известно сколько людей и как используют этот код, созданный еще в 2012 году. Может быть он встретится в очередном попсовом лайтбоксе, или в няшненьком jquery плагине, который, так получилось, написан без изысков, но уже сейчас очень нужно им использовать, чтобы не писать с нуля.

                          И когда кучи плагинов и библиотек начинают тянуть за собой всякие Cookie, Linq, Strings и Dates, то, иногда, (конечно не всегда) начинается жопа. Например, когда ваше громадное решение встраивается в страницу как API в чужое огромное решение.
                          То что вы не видите в этом проблемы не значит, что этой проблемы нет. Технический долг есть всегда и он даст о себе знать.

                          Вопрос по 5 фреймворкам адресуйте их создателям.

                          Не просите критики, если не готовы к ней.

                            +1
                            Ни одна из приведённых библиотек не может задать куки массивом, также удалять сразу несколько кук и получать. Также нет возможности получить все ключи, все куки. А метод clear реализован только у последнего. Из поиска могу выделить только несколько библиотек к сожалению.

                            Кстати код js-cookie метода noConflict прям в точь в точь из моего первого примера, только есть одно маленькое но они не освобождают пространство имён (Не удаляют переменную), а тупо создают клон мол сами удаляйте или перебивайте.

                            Пожалуй напишу метод noConflict. Ещё гетер length запилю, думаю пригодиться.

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

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