Сессионные (Session Storage) и локальные (Local Storage) хранилища данных на стороне клиента

Хранилище Web является спецификацией W3C, которая предоставляет функции для сохранения данных на стороне клиента до конца сеанса (Session Storage – сессионное хранилище), или после завершения сеанса (Local Storage – локальное хранилище). Это значительно более мощное средство, чем традиционные cookies, и более простое в использовании.

Прежде чем двигаться дальше, давайте коротко разберем, почему текущий способ хранения данных на стороне клиента — cookies — является проблемой:
  • Маленький размер: Cookies обычно имеют максимальный размер около 4KB, что не слишком хорошо подходит для хранения сложных данных любого вида.
  • С помощью cookies трудно отслеживать две или больше транзакций на одном и том же сайте, которые могут происходить в двух или более различных вкладках.
  • Cookies могут использоваться злонамеренно с помощью так называемой техники межсайтового скриптинга, что приводит к проблемам безопасности.

Другие (менее популярные) альтернативы для cookies включают методы, использующие строки запросов, скрытые поля форм, совместно используемые локальные объекты на основе flash, и т.д. Каждый со своим собственным набором проблем, связанным с безопасностью, легкостью использования, ограничениями на размер, и т.д. Поэтому до сих пор мы используем достаточно плохие способы хранения данных на стороне пользователя. Нам требуется улучшенный способ, и здесь на помощь приходит Хранилище Web.

Спецификация Хранилища Web W3C была разработана для улучшения способа хранения данных на стороне клиента. Она имеет два различных типа хранилища: Session Storage (Сессионное хранилище) и Local Storage (Локальное хранилище).

Как сессионное, так и локальное хранилище будут иметь возможность хранить около 5Mb данных на домен, что значительно больше чем cookies. По мере дальнейшего чтения вы больше узнаете о них, и о том, что делает хранилище Web более удобным механизмом хранения.

Сессионное хранилище

Сессионное хранилище имеет единственное предназначение: Запоминать все данные сеанса и забывать их, как только закрывается используемая вкладка (или окно).

Задание и извлечение данных

Чтобы задать пару ключ значение в сессионном хранилище, необходимо написать просто строку следующего вида:

sessionStorage.setItem(yourkey, yourvalue);

Чтобы снова извлечь данные, необходимо написать:

var item = sessionStorage.getItem(yourkey);

Чтобы сохранить значение "This is a sample sentence" в сессионном хранилище, можно написать:

sessionStorage.setItem(1, 'This is a sample sentence');

Здесь значением ключа будет 1, но это не значит, что это вообще первое значение. Число 1 просто преобразуется в строку '1', которая используется в качестве ключа, но это не помещает эту пару ключ значение в первую позицию.

А чтобы извлечь это предложение в предупреждающем сообщении JavaScript, необходимо написать:

var item = sessionStorage.getItem(1);
alert(item);

Другим примером setItem() может быть:

sessionStorage.setItem('name', 'john');

а извлечь значение можно с помощью

var name = sessionStorage.getItem('name');

Удаление данных

Существуют также методы для удаления данных из сессионного хранилища. Метод removeItem() используется для удаления определенного объекта из списка:

var item = sessionStorage.removeItem(yourkey);

Помните, что можно также сослаться просто на ключ объекта и удалить его из списка следующим образом:

var items = sessionStorage.removeItem(1);

Метод clear() используется для удаления всех объектов в списке; он применяется следующим образом:

sessionStorage.clear();

Можно использовать также атрибут length, чтобы определить число пар ключ/значение в хранилище, следующим образом:

var no_of_items = sessionStorage.length;

Локальное хранилище

Локальное хранилище используется, если требуется, чтобы данные сохранялись более чем для одного сеанса. Простым примером использования будет подсчет количества посещений пользователем страницы Web. Когда страница использует локальное хранилище, страница (или окно) можно закрыть и снова открыть, и, тем не менее, показать сохраненные данные — т.е. обеспечивается постоянное хранение.

Сохранение и извлечение данных в локальном хранилище работает аналогично сессионному хранилищу: оно использует такие же имена функций setItem() и getItem(). Чтобы сохранить предложение в локальном хранилище, нужно написать что-нибудь следующего вида:

localStorage.setItem(1, 'This is a sample sentence');

а чтобы извлечь его:

var data = localStorage.getItem(1);

Также как и сессионное хранилище, локальное хранилище поддерживает атрибут length, и функции removeItem() и clear().

Как в сессионном хранилище, так и в локальном функция clear() имеет одну задачу – удалить все значения из списка. Это означает, что если вызвать, например, функцию localStorage.clear(), то она удалит все локальное хранилище из этого источника. Поэтому все данные локального хранилища из, скажем, (такие как www.example.org, www.example.org:80, www.example.org/abc/, www.example.org/xyz/) будут удалены. Тем не менее, хранилище, скажем, для abc.example.org этим затронуто не будет. Однако для сессионного хранилища она будет очищать хранилище только для текущей сессии.

Простой пример

Чтобы проиллюстрировать хранилище Web в действии, был создан небольшой пример, который использует, как локальное, так и сессионное хранилище. Посмотрите демонстрационную страницу хранилища Web, чтобы увидеть его в действии. Пример попросит ввести две строки, одну для сессионного хранилища, и другую для локального хранилища. Затем можно открыть Storage Inspector в Opera Dragonfly, чтобы получить доступ к хранилищу Web. Можно заметить, что если закрыть страницу, а затем снова ее открыть, данные, введенные для локального хранилища, сохраняются, в то время как для сессионного хранилища, это будет не так.

Использование событий хранилища

Спецификация предоставляет также событие хранилища, которое будет порождаться, когда область хранилища изменяется. Оно имеет различные полезные атрибуты, такие как:
  • storageArea: Говорит, какой это тип хранилища (сессионное или локальное)
  • key: Изменяющийся ключ.
  • oldValue: Старое значение ключа.
  • newValue: Новое значение ключа.
  • url: URL страницы, ключ которой изменился.

Если вызвать метод clear(), то атрибуты key, oldValue и newValue устанавливаются пустыми. Здесь имеется модифицированная версия упомянутого ранее демонстрационного примера страницы, в этот раз использующая события хранилища, чтобы пользователи могли знать об изменениях в значениях. Если ввести значение, а затем снова его изменить, то можно будет видеть предупреждение, упоминающее новое и старое значения.

Детальный доступ к данным хранилища Web в Opera 10.50+

В Opera 10.50+ существует несколько способов, как это можно сделать. Можно ввести opera:webstorage, а также opera:config#PersistentStorage в поле адреса, чтобы получить доступ к высокоуровневым данным хранилища Web (какой лимит хранилища, где оно находится, и т.д.), но для разработчиков существует лучший способ получить подробную информацию о хранилище Web для конкретной страницы — с помощью Storage Inspector в Opera Dragonfly, который предоставляет значительно более подробную информацию.

Opera 10.50+ имеет новую и улучшенную утилиту отладки Opera Dragonfly (которая была опубликована как проект с открытым исходным кодом). Среди исправлений, усовершенствований и новых свойств появился Storage Inspector (Инспектор хранилища). Он создает для разработчиков отдельную вкладку для доступа к информации о cookies и локальном и сессионном хранилище страницы. Откройте Opera Dragonfly и щелкните на вкладке Storage, чтобы получить к ней доступ.

Что нужно помнить при использовании хранилища Web

Хранилище на источник: Все данные из одного и того же источника будут совместно использовать одно пространство хранения. Источником является тройка схема/хост/порт (или глобально уникальный идентификaтор). Например, http://www.example.org и http://abc.example.org являются двумя отдельными источниками, также как http://example.org и https://example.org, а также http://example.org:80 и http://example.org:8000

Лимит хранилища: В настоящее время большинство браузеров, которые реализовали хранилище Web, включая Opera, определяют лимит хранилища как 5 Mb на домен. Можно изменить этот лимит хранилища для каждого домена отдельно, сохраняя какие-то данные из домена в сеансовом или локальном хранилище, а затем переходя к opera:webstorage. Этот домен появится тогда в списке, и можно будет щелкнуть на кнопке, чтобы получить доступ к статистике и параметрам, включая размер данных, сохраненных для этого домена, какой имеется лимит хранилища, и что браузер будет делать, когда лимит будет исчерпан.

Вопросы безопасности и соответствующие рекомендации: Хранилище назначается на основе источника. Злоумышленник может использовать подмену DNS, чтобы представить себя определенным доменом, которым он фактически не является, получая тем самым доступ к области хранилища этого домена на компьютере пользователя. Можно использовать SSL, чтобы предотвратить такие действия, чтобы пользователи могли быть абсолютно уверены, что просматриваемый сайт находится в том же домене.

Где не надо использовать: Если два различных пользователя используют различные пути доступа на одном домене, они могут получить доступ к области хранения всего источника, и поэтому к данным друг друга. Поэтому в настоящее время не рекомендуется использовать хранилище Web на своих страницах пользователям свободных хостов, которые имеют свои сайты в различных каталогах одного и того же домена (например, freehostingspace.org/user1/ и freehostingspace.org/user2/ ).

Хранилище Web не является частью спецификации HTML5: Это целая спецификация сама по себе.

Тест

Указанный для кэширующихся файлов путь доступа должен задаваться относительно:
(Отметьте один правильный вариант ответа.)
Вариант 1 файла манифеста
Вариант 2 корневой директории сайта
Вариант 3 страницы приложения

Какой mime-тип должен иметь файл манифеста:
(Отметьте один правильный вариант ответа.)
Вариант 1 text/cache-manifest
Вариант 2 text/cache
Вариант 3 text/manifest

Какой раздел файла манифеста указывает браузеру список файлов, предназначенных для кэширования?
(Отметьте один правильный вариант ответа.)
Вариант 1 NETWORK
Вариант 2 FALLBACK
Вариант 3 CACHE

Отметьте корректные варианты проверки поддержки кэша приложений в браузере пользователя?
(Ответ считается верным, если отмечены все правильные варианты ответов.)
Вариант 1 if (window.applicationCache) { … }
Вариант 2 if (applicationCache) { … }
Вариант 3 if (application.Cache) { … }

Каким будет статус кэша приложений, если браузер имеет самую последнюю версию AppCache, и нет обновленных версий для загрузки?
(Отметьте один правильный вариант ответа.)
Вариант 1 downloading
Вариант 2 ready
Вариант 3 idle

Каким будет статус кэша приложений, если браузер не может найти файл манифеста?
(Отметьте один правильный вариант ответа.)
Вариант 1 updateready
Вариант 2 obsolete
Вариант 3 downloading

Какие события порождаются, если файл манифеста невозможно найти (ошибка загрузки 404 или 410)?
(Ответ считается верным, если отмечены все правильные варианты ответов.)
Вариант 1 obsolete
Вариант 2 abort
Вариант 3 error

С помощью какого обработчика событий можно определить, когда браузер производит загрузку кэша в первый раз, или загружает его обновленную версию?
(Отметьте один правильный вариант ответа.)
Вариант 1 oncaching
Вариант 2 ondownloading
Вариант 3 onupdate

Отметьте корректные способы заставить страницу использовать только что загруженный новый кэш?
(Ответ считается верным, если отмечены все правильные варианты ответов.)
Вариант 1 window.applicationCache.swapCache();
Вариант 2 window.swapCache();
Вариант 3 applicationCache.swapCache();

Как сохранить данные в сессионном хранилище?
(Отметьте один правильный вариант ответа.)
Вариант 1 sessionStorage.setItem(yourkey, yourvalue);
Вариант 2 sessionStorage.removeItem(yourkey);
Вариант 3 var item = sessionStorage.getItem(yourkey);

Как извлечь данные из локального хранилища?
(Отметьте один правильный вариант ответа.)
Вариант 1 localStorage.removeItem(yourkey);
Вариант 2 localStorage.setItem(yourkey, yourvalue);
Вариант 3 var data = localStorage.getItem(yourkey);

Какое событие позволяет определить адрес страницы, ключ которой изменился?
(Отметьте один правильный вариант ответа.)
Вариант 1 location
Вариант 2 history
Вариант 3 url

Для чего предназначен файл манифеста?
(Ответ считается верным, если отмечены все правильные варианты ответов.)
Вариант 1 указывает на файлы для альтернативной загрузки
Вариант 2 указывает на файлы, которые должны сохраняться в кэше приложений
Вариант 3 устанавливает дату хранения файлов приложения

Как сообщить странице о необходимости использования кэша приложений?
(Отметьте один правильный вариант ответа.)
Вариант 1 <manifest use="demo.manifest">
Вариант 2 <html manifest="demo.manifest">
Вариант 3 <meta name="manifest" value="demo.manifest">

Какой раздел файла манифеста указывает браузеру список файлов, предназначенных для кэширования?
(Отметьте один правильный вариант ответа.)
Вариант 1 FALLBACK
Вариант 2 NETWORK
Вариант 3 CACHE

Отметьте корректные варианты проверки статуса кэша приложений?
(Отметьте один правильный вариант ответа.)
Вариант 1 window.applicationCache
Вариант 2 window.applicationCache.status
Вариант 3 window.application.Cache.status

Каким будет статус кэша приложений, когда страница проверяет наличие обновленного файла манифеста?
(Отметьте один правильный вариант ответа.)
Вариант 1 checking
Вариант 2 check
Вариант 3 idle

Каким будет статус кэша приложений, когда браузер завершает загрузку нового кэша, он готов к использованию (но все еще не используется)?
(Отметьте один правильный вариант ответа.)
Вариант 1 downloading
Вариант 2 obsolete
Вариант 3 updateready

Какое событие порождается при возникновении фатальной ошибки в работе кэша приложений?
(Отметьте один правильный вариант ответа.)
Вариант 1 error
Вариант 2 onerror
Вариант 3 failure

Какой обработчик событий нужно использовать, чтобы определить окончание перезагрузки кэша приложений?
(Отметьте один правильный вариант ответа.)
Вариант 1 update
Вариант 2 updateready
Вариант 3 ready

Какие типы хранилищ предоставляет технология HTML5?
(Ответ считается верным, если отмечены все правильные варианты ответов.)
Вариант 1 глобальное хранилище (Global Storage)
Вариант 2 сессионное хранилище (Session Storage)
Вариант 3 локальное хранилище (Local Storage)

Какая функция удаляет все данные локального хранилища?
(Отметьте один правильный вариант ответа.)
Вариант 1 remove();
Вариант 2 clear();
Вариант 3 removeItem();

Какие события позволяют определить, что содержимое хранилища изменилось?
(Ответ считается верным, если отмечены все правильные варианты ответов.)
Вариант 1 newValue
Вариант 2 storageArea
Вариант 3 oldValue

С помощью какого оператора можно заставить браузер выходить в сеть по всем URL, если пользователь находится в сети?
(Отметьте один правильный вариант ответа.)
Вариант 1 *
Вариант 2 #
Вариант 3 $

Каким будет статус кэша приложений, если страница не кэширована?
(Отметьте один правильный вариант ответа.)
Вариант 1 not download
Вариант 2 unloaded
Вариант 3 uncached

Какое событие порождается, если процесс загрузки кэша приложений по какой-то причине должен быть прерван?
(Отметьте один правильный вариант ответа.)
Вариант 1 abort
Вариант 2 stopped
Вариант 3 error

Какой обработчик событий нужно использовать, чтобы определить окончание загрузки кэша приложений?
(Отметьте один правильный вариант ответа.)
Вариант 1 onloading
Вариант 2 oncached
Вариант 3 ondownloading

Как удалить элемент сессионного хранилища?
(Отметьте один правильный вариант ответа.)
Вариант 1 var sessionStorage.removeItem(yourkey);
Вариант 2 var sessionStorage.setItem(yourkey, yourvalue);
Вариант 3 var item = sessionStorage.getItem(yourkey);

С помощью какого события можно определить тип хранилища?
(Отметьте один правильный вариант ответа.)
Вариант 1 newValue
Вариант 2 storageArea
Вариант 3 oldValue