20.2.5. Реализация хранилища на основе cookies

We use cookies. Read the Privacy and Cookie Policy

Пример 20.2 демонстрирует, как поверх cookies можно реализовать методы, имитирующие прикладной интерфейс объекта Storage. Передайте конструктору СоokieStorage() желаемые значения атрибутов max-age и path и используйте получившийся объект подобно тому, как вы использовали бы localStorage или sessionStorage. Однако имейте в виду, что этот пример не реализует событие «storage» и не выполняет автоматическое сохранение или извлечение значений при записи или чтении свойств объекта CookieStorage.

Пример 20.2. Реализация интерфейса объекта Storage на основе cookies

/*

* CookieStorage.js

* Этот класс реализует прикладной интерфейс объекта Storage, на который ссылаются

* свойства localStorage и sessionStorage, но поверх HTTP Cookies.

*/

function CookieStorage(maxage, path) { // Аргументы определяют срок хранения

                                       // и область видимости

                                       // Получить объект, хранящий все cookies

var cookies = (function() {   // Функция getCookies(), реализованная выше

  var cookies = {};           // Возвращаемый объект

  var all = document.cookie;  // Получить все cookies в одной строке

  if (all === "")   // Если получена пустая строка

    return cookies; // вернуть пустой объект

  var list = all.split(";”); // Разбить на пары имя/значение

  for(var і = 0; і < list.length; i++) { // Для каждого cookie

    var cookie = list[і]:

    var p = cookie.indexOf("=");       // Отыскать первый знак =

    var name = cookie, substrings, p); // Получить имя cookie

    var value = cookie.substring(p+1); // Получить значение cookie

    value = decodeURIComponent(value); // Декодировать значение

    cookies[name] = value;             // Сохранить имя и значение

  }

  return cookies;

}());

// Собрать имена cookies в массиве

var keys = [];

for(var key in cookies) keys.push(key);

// Определить общедоступные свойства и методы Storage API

// Количество хранящихся cookies

this.length = keys.length; *

// Возвращает имя n-го cookie или null, если n вышло за диапазон индексов

this.key = function(n) {

  if (n < О И n >= keys.length) return null;

  return keys[n];

};

// Возвращает значение указанного cookie или null,

this.getltem = function(name) { return cookies[name] || null; };

// Сохраняет значение

this.setltem = function(key, value) {

  if (!(key in cookies)) { // Если cookie с таким именем не существует

    keys.push(key);        // Добавить ключ в массив ключей

    this.length++;         // И увеличить значение length

  }

  // Сохранить пару имя/значение в множестве cookies.

  cookies[key] = value;

  // Установить cookie.

  // Предварительно декодировать значение и создать строку

  // имя=кодированное-значение

  var cookie = key + "=" + encodeURIComponent(value);

  // Добавить в строку атрибуты cookie

  if (maxage) cookie += "; max-age=" + maxage;

  if (path) cookie += "; path=" + path;

  // Установить cookie с помощью свойства document.cookie

  document.cookie = cookie;

}

// Удаляет указанный cookie

this.removeItem = function(key) {

  if (!(key in cookies)) return; // Если не существует, ничего не делать

  // Удалить cookie из внутреннего множества cookies

  delete cookies[key];

  // И удалить ключ из массива имен.

  // Это легко можно было бы сделать с помощью метода indexOf() массивов,

  // определяемого стандартом ES5.

  for(var і = 0; і < keys.length; i++) { // Цикл по всем ключам

    if (keys[i] === key) { // При обнаружении ключа

      keys.splice(i,1); // Удалить его из массива,

      break;

    }

  }

  this.length--; // Уменьшить значение length

  // Наконец фактически удалить cookie, присвоив ему пустое значение

  // и истекший срок хранения.

  document.cookie = key + "=; max-age=0";

};