Статьи

Обзор API веб-хранилища

Веб-разработчики давно жаждут способа хранить данные в долгосрочной перспективе. Файлы cookie являются опцией, но они могут хранить только 4 КБ данных. Кроме того, куки отправляются на сервер с каждым HTTP-запросом. Это означает, что файлы cookie, особенно большие, могут потреблять значительную пропускную способность сети. Были и другие попытки реализовать методы хранения, но по большей части они были хаки. Затем на помощь пришли HTML5 и API веб-хранилища .

API веб-хранилища определяет два типа областей хранения — локальное хранилище и хранилище сеансов. Локальное хранилище — это постоянные данные, которые остаются до тех пор, пока они не будут явно удалены или пока кэш браузера не будет очищен. Согласно спецификации браузеры должны выделять как минимум 5 МБ локального хранилища на домен. Второй тип хранилища, хранилище сеансов, также является постоянными данными, однако данные связаны с «контекстом просмотра верхнего уровня» (т. Е. Вкладкой или окном браузера). Данные сеанса остаются до тех пор, пока они не будут удалены или контекст просмотра не будет закрыт. Хранение сеансов особенно полезно, когда пользователь взаимодействует с несколькими экземплярами одного и того же веб-сайта. В такой ситуации использование локального хранилища может привести к тому, что разные экземпляры будут перезаписывать данные друг друга.

Два типа областей хранения доступны через глобальные объекты с именами «localStorage» и «sessionStorage». Обе области хранения реализуют один и тот же API. Данные хранятся в виде пар ключ / значение, а все данные хранятся в виде строки. При добавлении данных в хранилище они неявно преобразуются в строку. Однако когда строковые данные извлекаются из хранилища, их необходимо явно преобразовать в соответствующий тип данных с помощью функций, таких как parseInt () . При работе с объектами следует использовать методы JSON.parse () и JSON.stringify () для сериализации и десериализации.

Обнаружение поддержки хранилища

API веб-хранилища, как и многие другие функции HTML5, поддерживается не всеми браузерами. Чтобы проверить, поддерживает ли браузер хранилище, используйте функцию, показанную ниже. Функция проверяет существование глобального объекта «localStorage». Аналогичная функция может быть создана для проверки хранилища сеансов, но можно смело предположить, что если одна область хранения существует, то и другая.

  function localStorageSupported () {
  пытаться {
   вернуть localStorage в окно && window ["localStorage"]! == null;
  } catch (e) {
   вернуть ложь;
  }
 } 

Хранение данных

Данные добавляются в хранилище с помощью метода setItem (). setItem () принимает ключ и значение в качестве аргументов. Если ключ еще не существует в хранилище, то добавляется пара ключ / значение. Если ключ уже присутствует, то значение обновляется. Несколько примеров использования setItem () показаны ниже. В примерах показано, как добавлять данные различных типов в локальное и сеансовое хранилище. Обратите внимание, что аргумент «ключ» всегда должен быть строкой, в то время как тип «значения» может отличаться.

  localStorage.setItem ("ключ", "значение");
 sessionStorage.setItem ("foo", 3.14);
 localStorage.setItem ("bar", true);
 sessionStorage.setItem ("baz", JSON.stringify (object)); 

Данные также могут быть добавлены в хранилище с помощью операторов присваивания свойств объекта. Предыдущие примеры setItem () были переписаны ниже с использованием операторов присваивания. Обратите внимание, что назначение «ключ» в первой строке произойдет сбой молча. Это потому, что области хранения имеют встроенную функцию с именем key (), которая будет рассмотрена позже. По этой причине методы API являются предпочтительным способом доступа к хранилищу.

  localStorage.key = "значение";  // молча не получается
 sessionStorage.foo = 3.14;
 localStorage ["bar"] = true;
 sessionStorage ["baz"] = JSON.stringify (object); 

Если сайт пытается сохранить слишком много данных, в конечном итоге квота хранилища браузера будет превышена, и будет выдано исключение. Чтобы справиться с этим случаем, блоки try-catch должны использоваться при хранении данных. Пример этого показан ниже.

  пытаться {
  localStorage.setItem ("ключ", "значение");
 } catch (e) {
  alert («Превышена квота хранилища!»);
 } 

Чтение сохраненных данных

Для чтения данных из хранилища используется метод getItem (). getItem () принимает ключ поиска в качестве единственного аргумента. Если ключ существует в хранилище, то возвращается соответствующее значение. Если ключ не существует, возвращается ноль. В следующих примерах метод getItem () используется для извлечения данных, хранящихся в примерах setItem ().

  var string = localStorage.getItem ("key");
 var number = sessionStorage.getItem ("foo");
 var boolean = localStorage.getItem ("bar");
 var object = JSON.parse (sessionStorage.getItem ("baz")); 

Доступ к сохраненным данным также можно получить, прочитав свойства объектов «localStorage» и «sessionStorage». Предыдущие примеры getItem () были переписаны ниже с использованием синтаксиса свойства объекта.

  var string = localStorage.key;
 var number = sessionStorage.foo;
 var boolean = localStorage ["bar"];
 var object = JSON.parse (sessionStorage ["baz"]); 

Итерация по сохраненным данным

Часто бывает необходимо программно зациклить все элементы в хранилище. Верхняя граница цикла определяется свойством «length» конкретной области хранения. Сохраненные ключи можно получить по одному, используя метод key (). key () принимает один целочисленный параметр, который действует как индекс для области хранения. Пример зацикливания каждой пары ключ / значение в «localStorage» показан ниже. Конечно, сессионное хранилище может обрабатываться аналогичным образом, заменяя «sessionStorage» на «localStorage».

  для (var i = 0; i <localStorage.length; i ++) {
  var key = localStorage.key (i);
  var value = localStorage.getItem (key);

  // сделать что-то с ключом и значением
 } 

Удаление сохраненных данных

Когда данные больше не нужны, они должны быть явно удалены. Это особенно верно для локального хранилища, поскольку оно будет сохраняться даже после закрытия браузера. Чтобы удалить отдельные пары ключ / значение из хранилища, используется метод removeItem (). Метод removeItem () принимает удаляемый ключ как единственный параметр. Если ключа нет, то ничего не произойдет. Примеры метода removeItem () показаны ниже.

  localStorage.removeItem ( "ключ");
 sessionStorage.removeItem ( "Foo");
 localStorage.removeItem ( "бар");
 sessionStorage.removeItem ( "БАЗ"); 

Оператор удаления также можно использовать для удаления сохраненных данных. Предыдущий пример переписан ниже с использованием delete вместо removeItem ().

  удалить localStorage.key;
 удалить sessionStorage.foo;
 удалить localStorage ["bar"];
 удалить sessionStorage ["baz"]; 

В то время как removeItem () используется для удаления отдельных фрагментов данных, метод clear () используется для удаления всех сохраненных данных. Использование метода clear () показано ниже.

  localStorage.clear ();
 sessionStorage.clear (); 

Событие хранения

Пользователь может потенциально открыть несколько экземпляров одного и того же сайта в любой момент времени. Изменения, внесенные в область хранения в одном экземпляре, должны быть отражены в других экземплярах. API веб-хранилища выполняет эту синхронизацию, используя событие «хранилище». Когда область хранения изменяется, событие «хранилище» запускается для любых других вкладок / окон, которые совместно используют область хранения. Обратите внимание, что событие «хранилище» не запускается для вкладки / окна, которое изменяет область хранения.

Области хранения могут быть изменены с помощью вызовов setItem (), removeItem () и clear (). Однако не все вызовы этих методов действительно изменяют область хранения. Например, вызов clear () для пустой области хранения или removeItem () для несуществующего ключа не изменит область хранения и, следовательно, не вызовет событие.

Объект события «хранилище» имеет несколько областей интереса, которые описаны ниже. После описания полей приведен пример обработчика событий «хранилище».

  • «Ключ» — это поле является ключевым аргументом setItem () или removeItem (), или null, когда clear () вызвало событие.
  • «NewValue» — в этом поле отражается аргумент «value» для setItem (). Вызовы removeItem () и clear () приводят к тому, что это поле становится пустым.
  • «OldValue» — это поле содержит значение ключа до вызова setItem () или removeItem (). При вызове clear () это поле становится пустым.
  • «Url» — в поле «url» хранится адрес страницы, область хранения которой была затронута.
  • «StorageArea» — поле «storageArea» соответствует локальной области хранения или области хранения сеанса, которая была изменена.
  window.addEventListener ("хранилище", функция (событие) {
  var key = event.key;
  var newValue = event.newValue;
  var oldValue = event.oldValue;
  var url = event.url;
  var storageArea = event.storageArea;

  // обрабатывать событие
 }); 

Пример страницы

Следующий код реализует пример страницы для управления локальным хранилищем. Страница также доступна онлайн здесь . Пример охватывает весь API локального хранилища, включая событие «хранилище». Чтобы увидеть событие «хранилище» в действии, страница должна быть открыта как минимум в двух отдельных вкладках / окнах одного и того же браузера. Событие «storage» также будет работать, только если страница обслуживается по HTTP (т. Е. Протокол file: // не будет работать).

  <! DOCTYPE html>
 <HTML>
 <Голова>
  <title> Пример веб-хранилища </ title>
  <meta charset = "UTF-8" />
  <Скрипт>
   «использовать строгое»;
   window.addEventListener ("загрузка", функция (событие) {
    var key = document.getElementById ("key");
    var value = document.getElementById ("value");
    var add = document.getElementById ("add");
  var remove = document.getElementById ("remove");
  var clear = document.getElementById ("clear");
  var content = document.getElementById ("content");

    add.addEventListener ("click", function (event) {
 if (key.value! == "") {
      пытаться {
   localStorage.setItem (key.value, value.value);
      } catch (e) {
       alert («Превышена квота хранилища!»);
      }
  refreshContents ();
  }
  });

  remove.addEventListener ("click", function (event) {
  if (key.value! == "") {
  localStorage.removeItem (key.value);
  refreshContents ();
  }
  });

  clear.addEventListener ("click", function (event) {
  localStorage.clear ();
  refreshContents ();
  });

  window.addEventListener ("хранилище", функция (событие) {
  var k = event.key;
  var newValue = event.newValue;
  var oldValue = event.oldValue;
  var url = event.url;
  var storageArea = event.storageArea;

  alert («СОБЫТИЕ: n» + k + «n» + newValue + «n» + oldValue + «n» + url + «n» + storageArea);
  refreshContents ();
  });

  function refreshContents () {
  var str = "";

  для (var i = 0, len = localStorage.length; i <len; i ++) {
  var k = localStorage.key (i);
  var v = localStorage.getItem (k);

  str + = "'" + k + "' = '" + v + "' <br />";
  }

     key.value = "";
     value.value = "";
  content.innerHTML = str;
  }

  refreshContents ();
  });
  </ Скрипт>
 </ HEAD>
 <Тело>
  Ключ: <input type = "text" id = "key" /> <br />
  Значение: <input type = "text" id = "value" /> <br />
  <input type = "button" id = "add" value = "Добавить в хранилище" /> & nbsp;
  <input type = "button" id = "remove" value = "Удалить из хранилища" /> & nbsp;
  <input type = "button" id = "clear" value = "Очистить хранилище" /> <br />
  Содержимое локального хранилища: <br />
  <span id = "content"> </ span>
 </ Body>
 </ Html> 

То, что нужно запомнить

  • Локальное хранилище сохраняется до тех пор, пока оно не будет явно удалено или не очищен кэш браузера
  • Хранение сеанса сохраняется до тех пор, пока оно не будет явно удалено или контекст просмотра не будет закрыт.
  • Данные, хранящиеся в одном браузере, недоступны для другого браузера. Например, данные, хранящиеся в Chrome, не видны в Firefox.
  • Объекты должны храниться в виде строк JSON.
  • В целях безопасности конфиденциальные данные не должны храниться, особенно в локальном хранилище.
  • Изменения в области хранения вызывают запуск события «хранение».
  • Как и со многими другими функциями HTML5, веб-хранилище еще не реализовано согласованно.

Хранение изображения через Shutterstock