DOM Storage guide

Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

 

DOM хранилище (DOM Storage) - это название для набора инструментов, относящихся к хранилищам, впервые представленных в спецификации Web Applications 1.0,  и выделенных теперь в отдельную специкацию W3C Web Storage. DOM хранилище было разработано с целью предоставления альтернативы хранению информации в кукисах. Предполагается, что DOM хранилище предоставляет больше объема, оно более защищено и легче в использовании. Впервые оно было представлено  в браузерах Firefox 2 и Safari 4.

Заметка: DOM хранилище - это не то же самое, что mozStorage (Mozilla's XPCOM interfaces to SQLite) или Session store API (утилита XPCOM - хранилище для использования в расширениях).

Заметка: Эта статья скоро будет сильно переработана. Вместо того, чтобы хранить всю информацию на одной странице, она будет разбита на несколько статей, каждая из которых будет описывать разные API хранилища. Отдельная статья, помогающая разобраться в разных API, будет также добавлена.

Описание

Механизм DOM хранилища - средство, благодаря которому можно безопасно хранить и позже извлекать пары "ключ / значение". Целью этого является обеспечение комплексного средства, с помощью которого можно разрабатывать интерактивные приложения(включая приложения с продвинутыми возможностями, такими как возможность работать "автономно"("offline") в течение длительных периодов времени).

Браузеры на основе Mozilla, Internet Explorer 8 +, Safari 4 + и Chrome обеспечивают рабочую реализацию спецификации DOM хранилища. (В случае, если нужна кросс-браузерная поддержка функциональности, включая более старые версии IE, будет полезно отметить, что IE также имеет подобную легаси функциональность под названием "USERDATA поведение", которая дополненяет DOM хранилище IE в IE8.)

DOM хранилище удобно, потому что нет других хороших способов хранения разумных объемов данных за любой период времени, встроенных в браузер. Кукисы ограничены в количестве хранимой информации и не обеспечивают поддержку для организации постоянных данных, а другие методы (например, флэш-локальное хранилище) требуют плагина.

Одним из первых известных приложений,  использующих новые функциональные возможности DOM хранилища(в дополнение к USERDATA поведения в Internet Explorer) было halfnote (приложение для заметок), написанное Аароном Будменом. В своем приложении, Аарон одновременно сохранял заметки на сервере (когда/если Интернет-подключение  был доступно) и локального хранилища данных(в обратном случае). Это дало возможность пользователю смело писать резервные копии заметок даже при нерегулярном подключении к Интернету.

Хотя идея и реализация halfnote были сравнительно простыми, создание halfnote показывает возможность для нового поколения веб-приложений, которые можно использовать как в онлайн-, так и оффлайн- режиме.

Связь

Ниже приведены глобальные объекты, которые существуют как свойства каждого объекта  window. Это означает, что они могут быть доступны как sessionStorage или window.sessionStorage. (Это важно, потому что вы можете использовать фреймы(IFrames) для хранения или доступа, дополнительные данные кроме того, что сразу же включено на странице.)

Storage

Это конструктор(Storageдля всех экземпляров Storage (sessionStorage и globalStorage[location.hostname]).

Сохранение Storage.prototype.removeKey = function(key){ this.removeItem(this.key(key)) } будет доступно через localStorage.removeKey и sessionStorage.removeKey.

Единицы globalStorage являются экземплярами StorageObsolete, а не Storage.

Storage определен в WhatWG Storage Interface следующим образом:

interface Storage {
  readonly attribute unsigned long length;
  [IndexGetter] DOMString key(in unsigned long index);
  [NameGetter] DOMString getItem(in DOMString key);
  [NameSetter] void setItem(in DOMString key, in DOMString data);
  [NameDeleter] void removeItem(in DOMString key);
  void clear();
};
Заметка: Несмотря на то, что значения доступны для чтения и записи через стандартные способы Javascript, рекомендуется использование getItem и setItem.
Заметка: Обратите внимание, что любые данные, которые хранятся в любом из хранилищ, описанных на этой странице, преобразуются в строку, используя метод.toString. перед тем, как сохранить значение. Попытка сохранить объект приведет к сохранению строки "[object Object]"  вместо объекта или его JSON представления. Самым лучшим и распространенным способом сохранения объектов в формате строки является использование предоставляемых браузером методов JSON для парсинга и сериализации объектов.

sessionStorage

Это глобальный объект (sessionStorage), который сохраняет значения, которые доступны в течение периода текущей сессии. Сессия страницы длится, пока браузер открыт, и восстанавливает свои значения после перегрузки страницы. Открытие страницы в новой вкладке или окне приведет к созданию новой сессии для этой страницы.

// Сохранить данные в текущем хранилизе сессий
sessionStorage.setItem("username", "John");

// Получить значения сохраненного значения
alert( "username = " + sessionStorage.getItem("username"));

Объект sessionStorage наиболее полезен для хранения временных данных, которые должны быть восстановлены, если страница браузер была случайно перегружена.

Примеры:

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

 // Получить значение текстового поля, которое мы собираемся отслеживать
 var field = document.getElementById("field");
 
 // Проверяем, что значение поля autosave существует
 // (это будет происходить при случайной перезагрузке страницы)
 if (sessionStorage.getItem("autosave")) {
    // Восстановить значение тестового поля
    field.value = sessionStorage.getItem("autosave");
 }
 
 // Прослушивать изменения значения текстового поля
 field.addEventListener("change", function() {
    // И сохранить результаты в объект хранилища сессий
    sessionStorage.setItem("autosave", field.value);
 });

Больше информации:

localStorage

localStorage - это то же самое, что и sessionStorage, поддерживает правила единого происхождения(same-origin rules), но хранение данных постоянно. localStorage был представлен в Firefox 3.5.

Заметка: Когда браузер переходит в частный режим браузера(private browsing mode), то новая, временная база данных создается для хранения данных локального хранилища; эта база данных очищается и удаляется, как только частный режим браузера выключается.

Совместимость

Объекты Storage - относительно недавнее дополнение стандарта. Это означает, что они не обязательно должны быть реализованы во всех браузерах. Проблему можно решить с помощью включения следующего куска кода в начале вашего скрипта, позволяя использовать объект localStorage в реализациях, которые нативно не поддерживают его.

Следующий алгоритм - это точная имитация объекта localStorage, но использует куки.

if (!window.localStorage) {
  Object.defineProperty(window, "localStorage", new (function () {
    var aKeys = [], oStorage = {};
    Object.defineProperty(oStorage, "getItem", {
      value: function (sKey) { return sKey ? this[sKey] : null; },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, "key", {
      value: function (nKeyId) { return aKeys[nKeyId]; },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, "setItem", {
      value: function (sKey, sValue) {
        if(!sKey) { return; }
        document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
      },
      writable: false,
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, "length", {
      get: function () { return aKeys.length; },
      configurable: false,
      enumerable: false
    });
    Object.defineProperty(oStorage, "removeItem", {
      value: function (sKey) {
        if(!sKey) { return; }
        document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
      },
      writable: false,
      configurable: false,
      enumerable: false
    });
    this.get = function () {
      var iThisIndx;
      for (var sKey in oStorage) {
        iThisIndx = aKeys.indexOf(sKey);
        if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
        else { aKeys.splice(iThisIndx, 1); }
        delete oStorage[sKey];
      }
      for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
      for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) {
        aCouple = aCouples[nIdx].split(/\s*=\s*/);
        if (aCouple.length > 1) {
          oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]);
          aKeys.push(iKey);
        }
      }
      return oStorage;
    };
    this.configurable = false;
    this.enumerable = true;
  })());
}
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.setItem() and localStorage.removeItem() to add, change, or remove a key. The use of methods localStorage.yourKey = yourValue; and delete localStorage.yourKey; to set or delete a key is not a secure way with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.

Here is another, less exact, imitation of the localStorage object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8 (tested and working even in Internet Explorer 6). It also makes use of cookies.

if (!window.localStorage) {
  window.localStorage = {
    getItem: function (sKey) {
      if (!sKey || !this.hasOwnProperty(sKey)) { return null; }
      return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1"));
    },
    key: function (nKeyId) {
      return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]);
    },
    setItem: function (sKey, sValue) {
      if(!sKey) { return; }
      document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
      this.length = document.cookie.match(/\=/g).length;
    },
    length: 0,
    removeItem: function (sKey) {
      if (!sKey || !this.hasOwnProperty(sKey)) { return; }
      document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
      this.length--;
    },
    hasOwnProperty: function (sKey) {
      return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
    }
  };
  window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
}
Note: The maximum size of data that can be saved is severely restricted by the use of cookies. With this algorithm, use the functions localStorage.getItem(), localStorage.setItem(), and localStorage.removeItem() to get, add, change, or remove a key. The use of method localStorage.yourKey in order to get, set, or delete a key is not permitted with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object.
Note: By changing the string "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" to: "; path=/" (and changing the object's name), this will become a sessionStorage polyfill rather than a localStorage polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.

Compatibility and relation with globalStorage

localStorage is also the same as globalStorage[location.hostname], with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage being an instance of Storage as opposed to globalStorage[location.hostname] being an instance of StorageObsolete which is covered below. For example, http://example.com is not able to access the same localStorage object as https://example.com but they can access the same globalStorage item. localStorage is a standard interface while globalStorage is non-standard so you shouldn't rely on these.

Please note that setting a property on globalStorage[location.hostname] does not set it on localStorage and extending Storage.prototype does not affect globalStorage items; only extending StorageObsolete.prototype does.

globalStorage

Не стандартно
Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

Вышла из употребления с версии Gecko 13.0 (Firefox 13.0 / Thunderbird 13.0 / SeaMonkey 2.10)
Эта возможность вышла из употребления. Хотя она может продолжать работать в некоторых браузерах, её использование не рекомендуется, поскольку она может быть удалена в любое время. Старайтесь избегать её использования.

globalStorage is obsolete since Gecko 1.9.1 (Firefox 3.5) and unsupported since Gecko 13 (Firefox 13). Just use localStorage instead. This proposed addition to HTML5 has been removed from the HTML5 specification in favor of localStorage, which is implemented in Firefox 3.5. This is a global object (globalStorage) that maintains multiple private storage areas that can be used to hold data over a long period of time (e.g., over multiple pages and browser sessions).

Note: globalStorage is not a Storage instance, but a StorageList instance containing StorageObsolete instances.
// Save data that only scripts on the mozilla.org domain can access
globalStorage['mozilla.org'].setItem("snippet", "<b>Hello</b>, how are you?");

Specifically, the globalStorage object provides access to a number of different storage objects into which data can be stored. For example, if we were to build a web page that used globalStorage on this domain (developer.mozilla.org) we'd have the following storage object available to us:

  • globalStorage['developer.mozilla.org'] - All web pages within the developer.mozilla.org sub-domain can both read and write data to this storage object.

Examples:

All of these examples require that you have a script inserted (with each of the following code) in every page that you want to see the result on.

Remember a user's username for the particular sub-domain that is being visited:

 globalStorage['developer.mozilla.org'].setItem("username", "John");

Keep track of the number of times that a user visits all pages of your domain:

 // parseInt must be used since all data is stored as a string
 globalStorage['mozilla.org'].setItem("visits", parseInt(globalStorage['mozilla.org'].getItem("visits") || 0 ) + 1);

Расположение хранилища и очищение данных

In Firefox the DOM storage data is stored in the webappsstore.sqlite file in the profile folder (there's also chromeappsstore.sqlite file used to store browser's own data, notably for the start page - about:home, but potentially for other internal pages with "about:" URLs).

  • DOM Storage can be cleared via "Tools -> Clear Recent History -> Cookies" when Time range is "Everything" (via nsICookieManager::removeAll)
    • But not when another time range is specified: (bug 527667)
    • Does not show up in Tools -> Options -> Privacy -> Remove individual cookies (bug 506692)
  • DOM Storage is not cleared via Tools -> Options -> Advanced -> Network -> Offline data -> Clear Now.
  • Doesn't show up in the "Tools -> Options -> Advanced -> Network -> Offline data" list, unless the site also uses the offline cache. If the site does appear in that list, its DOM storage data is removed along with the offline cache when clicking the Remove button.

See also clearing offline resources cache.

Больше информации

Примеры

  • JavaScript Web Storage Tutorial: Creating an Address Book Application - Hands-on tutorial describing how to use the Web Storage API by creating a simple address book application.
  • offline web applications at hacks.mozilla.org - Showcases an offline app demo and explains how it works.
  • Noteboard - Note writing application that stores all data locally.
  • jData - A shared localStorage object interface that can be accessed by any website on the internet and works on Firefox 3+, Webkit 3.1.2+ nightlies, and IE8. Think of it as pseudo-globalStorage[""] but write access needs user confirmation.
  • HTML5 localStorage example - Very simple and easy to understand example of localStorage. Saves and retrieves texts and shows a list of saved items. Tested in Firefox 3 or higher.
  • HTML5 Session Storage - A very simple example of session storage. Also includes a example on local storage. Tested in Firefox 3.6 or higher.
  • Basic DOMStorage Examples - Broken in Firefox 3 and up due to use of globalStorage on one domain level up from the current domain which is not allowed in Firefox 3.
  • halfnote - (displaying broken in Firefox 3) Note writing application that uses DOM Storage.

Совместимость с браузерами

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
localStorage 4 3.5 8 10.50 4
sessionStorage 5 2 8 10.50 4
globalStorage Нет 2-13 Нет Нет Нет
Feature Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Basic support 2.1 ? 8 11 iOS 3.2

All browsers have varying capacity levels for both localStorage and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.

Note: since iOS 5.1, Safari Mobile stores localStorage data in the cache folder, which is subject to occasional clean up, at the behest of the OS, typically if space is short.

Полезные ссылки

Метки документа и участники

 Внесли вклад в эту страницу: Steln, akhabibullina
 Обновлялась последний раз: Steln,