Javascript.RU

Хранение данных на клиенте. DOM Storage и его аналоги.

По мере того как web-странички превращаются в AJAX-приложения, им требуются все новые возможности.

Сложные выборки элементов DOM обеспечиваются некоторыми браузерами и почти всеми распространенными Javascript-фреймворками.

Кросс-доменные HTTP-запросы находят поддержку в стандартах и реализуются в новейших браузерах, включая Internet Explorer 8.

В этой статье пойдет речь о средствах для хранения большого количества данных на клиенте, в браузере, которые доступны уже сейчас.

В частности, Internet Explorer 5+, Firefox 2+, Safari 2+ не требуют для этого дополнительных плагинов и Flash.

UPDATE: статья устарела и будет переписана.

Почти во всех браузерах есть поддержка cookies.

На протяжении долгого времени cookies были единственным кросс-браузерным способом сохранить данные, которые будут доступны после перезагрузки страницы.

Однако у cookie есть две важных особенности:

  1. Не более 2 килобайт данных
  2. Данные идут на сервер при каждом HTTP-запросе

Средства хранения на клиенте предусматривают сотни килобайт и мегабайты данных, и не отсылают их на сервер при каждом HTTP-запросе.

А cookie можно продолжать использовать, например, для хранения сессии.

Firefox реализует стандарт хранения "Client-side session and persistent storage of name/value pairs", предложенный в спецификации HTML 5.

Для постоянного хранения данных в нем используется объект window.globalStorage[домен], операции над которым можно производить точно так же, как над обычным javascript-объектом. При уходе с сайта и даже закрытии браузера globalStorage не меняется, так что все его свойства можно прочитать обратно.

Например:

storage = globalStorage[document.domain]

// записать значение
storage['userName'] = 'Vasya'
// прочитать значение
alert(storage['userName'])
// удалить значение
delete storage['userName']

// получить все значения
for(var name in storage) {
    alert(name + ':' + storage[name])
}

При чтении/записи на элементе body инициируется всплывающее событие storage.

Поймать его можно, например, таким обработчиком:

window.addEventListener('storage', function(event) { ... })

Стандарт HTML 5 все еще в процессе развития. В старой редакции прочитанные значения имели тип StorageItem.

Версия Firefox 2.0.0.13 возвращает при чтении объект именно этого типа.

Из текущей редакции StorageItem убран. В ней возвращаемые хранилищем значения имеют более простой тип DOMString.

..А пока эти изменения не учтены разработчиками, рекомендуется преобразовать значения к String явным образом.

Например:

var test = "12345"
storage.test = test // сохранить -> String
test = storage.test // прочитать <- StorageItem

alert(test.length) // undefined, это же не строка
alert(test.constructor) // StorageItem

test = String(test) // сделали строку. Теперь все ок.

Ограничения на данные: ключи и значения - только строки.

Размер: 5MB на домен.

Ограничения безопасности - точно такие же, как на cookie.
Данные в globalStorage['site.ru'] можно сохранить только на самом site.ru, а прочитать - на blog.site.ru, но не на otherhost.ru.

Internet Explorer 8 реализует DOM Storage, в то время как версии начиная от 5й поддерживают собственный интерфейс: userData behavior.

Он работает посредством выделенного DOM-элемента, которому назначается behavior userData. В этот элемент загружается нужное пространство имен, и данные становятся доступны через атрибуты.

<span id="storageElement"></span>
<script>    
    storage = document.getElementById('storageElement')
    if (!storage.addBehavior) {
        alert("userData not available.")
    } else {
        // поставить userData behavior
        storage.addBehavior("#default#userData")
        // загрузить пространство имен
        storage.load("namespace")    
    }
</script>

После инициализации можно работать с данными. Для записи изменений используется метод save.

function put(key, value) { // записать значение
    storage.setAttribute(key, value)
    storage.save("namespace")
}

function get(key) { // получить значение
    return storage.getAttribute(key)
}

function remove(key) { // удалить значение
    storage.removeAttribute(key)
    storage.save("namespace")
}

Как это часто бывает с Internet Explorer, некоторые операции делаются неочевидным образом.

Так, например, получить все сохраненные данные из storage.attributes нельзя. Там хранятся только атрибуты самого HTML-элемента.

Данные же хранятся в свойстве storage.XMLDocument.documentElement.attributes.

Например, следующий код создает список вида ключ:значение.

var list = []
var attrs = storage.XMLDocument.documentElement.attributes
        
for(var i=0; i<attrs.length; i++) {
    list.push(attrs[i].name+':'+attrs[i].value);
}

В отличие от DOM Storage, можно задать атрибут expires. Он устанавливается на уровне всего элемента и действует на все хранящиеся данные. Очистка данных происходит при вызове load.

var time = new Date(); // Start Time
time.setMinutes(time.getMinutes() + 1)
storage.expires = time.toUTCString();

Ключи и значения - только строки.

Способ работает при всех уровнях безопасности, кроме "Высокого".
При этом для сайтов в зоне Internet объем ограничен 128K на страницу и 1024K на домен, для локальных и интранет - лимит увеличен.

Ограничения безопасности - та же директория, тот же домен и протокол.

Дальше всех в поддержке стандарта хранения пошли разработчики WebKit.
В Safari реализовано локальное хранение в базе данных SQLite.

Набор операций включает в себя CREATE TABLE, INSERT, SELECT, REPLACE, индексы и многое другое, с рядом ограничений безопасности (например, нет LOAD DATA INFILE).

В отличие от DOM Storage и userData, этот интерфейс асинхронный. Все функции запросов к базе данных принимают в качестве аргументов две функции: callback - для обработки результатов и errback - для обработки ошибок.

Когда запрос завершается, вызывается один из этих обработчиков.

Продемонстрируем это на тестовой базе.

db = openDatabase("Test", "1.0", "Webkit Storage Example")

db.transaction(function(tx) {
  tx.executeSql(
      "CREATE TABLE IF NOT EXISTS test (key TEXT, value TEXT, unique(key))", 
      [], 
      function(tx, result) { alert("Success!") },
      function(tx, error) { alert("Failure: "+error.message }
  )
})

Сложновато с первого взгляда?

db.transaction создает транзакцию и передает ее функции-аргументу.

Код внутри function(tx) выполняется в одной транзакции.

Вызов tx.executeSql принимает аргументы:

  1. Запрос
  2. Аргументы подстановки
  3. Обработчик результата
  4. Обработчик ошибки

Следующий пример демонстрирует обработку запроса.

db.transaction(function(tx) {
  tx.executeSql("SELECT value FROM test WHERE key=?", [key],
    function(tx,result) {
      alert("Количество результатов: "+result.rows.length)
      alert("Поле value первого результата: "+ result.rows.item(0).value)
   },
   function(tx, error) { alert("Error!") }
  )
})

Стандарт SQL-хранения также включает в себя поддержку версий схемы, указание размера базы данных в openDatabase и многое другое. Может существовать только одна версия схемы одновременно.

База существует только в рамках домена(полного домена, origin), на котором была создана. Поддомен не имеет доступа к базе домена.

На момент написания статьи разработчики WebKit планировали поддержку DOM Storage, но в nightly build ее не было.

На момент написания статьи Opera 9.5 (beta) не поддерживает ни DOM Storage ни Database Storage.

С другой стороны, разработчики планируют эту поддержку включить.

Там, где нет DOM Storage, для offline-хранения используют flash-интерфейс SharedObject. Он позволяет хранить самые разные объекты средствами Adobe Flash.

Пример ActionScript для работы с SharedObject:

// создать/получить namespace storage
storage = SharedObject.getLocal("storage"); 

// записать данные name => Вася
storage.data.name="Вася";

// сохранить объект
storage.flush()

// перечислить свойства объекта
for (var name in storage.data) {
    trace(name + ":" + storage.data[name])
}

Чтобы работать с этим хранилищем из javascript, нужен способ коммуникации JS<->Flash.

В старых версиях Flash вызвать javascript можно через getURL('javascript:...').

Передать значение во Flash можно установкой переменной flash-объекту. Эту переменную flash-ролик может считывать каждый кадр и предпринимать соответствующие действия.

Во Flash 8+ появился интерфейс ExternalInterface, который позволяет как указывать AS-функцию для приема данных из JS, так и напрямую вызывать JS-метод.

Открыть рабочий пример передачи значения Flash <-> JS.

Код примера в ActionScript:

import flash.external.*;

// установить местную функцию recieveFromJS для приема данных
// от javascript-функции sendFromJS
ExternalInterface.addCallback("sendFromJS", null, recieveFromJS);

// Эта функция будет реагировать на sendFromJS
function recieveFromJS(text) {
    _root.theText.text = text; // .. и устанавливать текст в окошке
}

// Это действие, наоборот, отправляет данные в JS.
_root.button.onRelease = function() {
    // вызвать javascript-функцию recieveFromFlash
    ExternalInterface.call("recieveFromFlash", _root.theText.text);
    _root.theText.text = "";
}

Код примера в JS:

function recieveFromFlash(Txt) {
	document.getElementById('text').value = Txt;
}

function sendFromJS() {
    var value = document.getElementById('text').value
    
    var movie = (navigator.appName.indexOf("Microsoft")!=-1 ? window : document)["BridgeMovie"]    
    
    movie.sendFromJS(value);    

    document.getElementById('text').value = ''
}

Скачать исходники

Документация на ExternalInterface

Доступ к SharedObject ограничен роликами с того же домена.

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

Ограничение по умолчанию на размер данных - в районе 100Kb, пользователь может уменьшить или увеличить его в специальном Flash-интерфейсе, который открывается при вызове ActionScript:

System.showSettings(1);

Во-первых, надо иметь Flash. Хранилище доступно только после инициализации Flash-ролика.

Много ошибок в различных версиях Flash затрагивают ExternalInterface, включая повреждение данных во время передачи JS->Flash.

Проще всего узнать о них:

Много работы над обходом багов провел Brad Neuberg для flash-хранилища в dojo:

  • dojox/storage - различные хранилища, включая flash
  • dojox/flash - кроссбраузерная js/flash коммуникация, необходима для dojox/storage

DOM Storage и аналогичные системы хранения - важный шаг к offline-работе web-приложений.

DOM Storage поддерживается всеми современными браузерами.

Интересным сектором для интеграции могут быть CRM-системы с нестабильным интернетом. Например, мини-точка продаж, в которой основная работа идет через интеренет, но хранение текущих договоров дублируется на рабочей машине.

Offline-хранилище может быть использовано для сохранения сложных состояний интерфейса - размеров окон, контрольных элементов и т.п.

Все изменения интерфейса посетителем мгновенно сохранятся в DOM Storage и восстановятся при следующем заходе на страницу без дополнительных механизмов сохранения интерфейса на сервере.

При этом объем хранимого состояния интерфейса вряд ли превысит ограничение в сотни килобайт. Идеальный объект для DOM Storage, не правда ли ?..


Автор: 온라인바카라사이트 (не зарегистрирован), дата: 17 апреля, 2023 - 13:09
#permalink

Your ideas inspired me very much. 온라인바카라사이트 It's amazing. I want to learn your writing skills. In fact, I also have a website. If you are okay, please visit once and leave your opinion. Thank you.


Автор: 다바오홀덤 (не зарегистрирован), дата: 27 апреля, 2023 - 05:07
#permalink

I’m not sure exactly why but this weblog is loading incredibly slow for me. Is anyone else having this problem or is it a problem on my end? I’ll check back later on and see if the problem still exists. 다바오홀덤


Автор: 토토사이트 (не зарегистрирован), дата: 29 апреля, 2023 - 10:57
#permalink

That's a great article! The neatly organized content is good to see. Can I quote a blog and write it on my blog? My blog has a variety of communities including these articles. Would you like to visit me later? 토토사이트


Автор: poppy pods for sell (не зарегистрирован), дата: 30 апреля, 2023 - 13:30
#permalink

I am helpful that I found this website, with precisely the right info that I was searching
For! poppy pods for sell Thanks for the informative post.


Автор: Weed Delivery open late (не зарегистрирован), дата: 2 мая, 2023 - 19:54
#permalink

This article is great as well as inspiring. Affordable assignment helps You put information that's really very helpful. Weed Delivery open late I'm going to share this with my friends.


Автор: 500 Rounds of 7.62x39mm Ammo by Tula (не зарегистрирован), дата: 4 мая, 2023 - 15:48
#permalink

This is a great site! I am very happy to read this article. 500 Rounds of 7.62x39mm Ammo by Tula Thanks for giving us go thorough info. Fantastic, for taking the time to write it!


Автор: 토지노 (не зарегистрирован), дата: 5 мая, 2023 - 07:44
#permalink

Hello, I'm happy to see some great articles on your site. Would you like to come to my site later? My site also has posts, comments and communities similar to yours. Please visit and take a look 토지노


Автор: 토토사이트 (не зарегистрирован), дата: 6 мая, 2023 - 06:28
#permalink

What a post I've been looking for! I'm very happy to finally read this post.토토사이트 Thank you very much. Can I refer to your post on my website? Your post touched me a lot and helped me a lot. If you have any questions, please visit my site and read what kind of posts I am posting. I am sure it will be interesting.


Автор: 메이저사이트 (не зарегистрирован), дата: 10 мая, 2023 - 11:48
#permalink

Hello! I could have sworn I've been to this site before but after checking through some of the post I realized it's new to me. Nonetheless, I'm definitely happy I found 메이저사이트 and I'll be book-marking and checking back frequently!


Автор: weed delivery in west covina (не зарегистрирован), дата: 12 мая, 2023 - 15:35
#permalink

Nice article. Thanks for sharing this article with us. weed delivery in west covina Keep sharing more related blogs. Great work!


Автор: Donadickey (не зарегистрирован), дата: 17 мая, 2023 - 18:50
#permalink

B+ Mushrooms Online Sales.
Buy Cubensis B+ Magic Mushroom Online. Psilocybe cubensis is a species of psychedelic mushroom whose principal active compounds are psilocybin and psilocin. Commonly called shrooms, magic mushrooms, golden tops, cubes, or gold caps, it belongs to the fungus family Hymenogastraceae and was previously known as Stropharia cubensis. Cubensis B+ magic mushrooms for sale purchasepsychedelics.com. order from B+ Mushrooms Online Sales


Автор: Beretta A300 Ultima Semi-Auto Shotgun (не зарегистрирован), дата: 23 мая, 2023 - 15:31
#permalink

I am helpful that I found this website, with precisely the right info that I Beretta A300 Ultima Semi-Auto Shotgun was searching
For! Thanks for the informative post.


Автор: trippyplug (не зарегистрирован), дата: 24 мая, 2023 - 17:04
#permalink

I am helpful that I found this website, with precisely the right info that I trippyplug was searching
For! Thanks for the informative post.


Автор: 5 meo DMT for sale (не зарегистрирован), дата: 31 мая, 2023 - 15:43
#permalink

You are a very persuasive writer. Keep up the great work, its hard to find good ones. 5 meo DMT for sale

Truly, one of the best posts I've ever witnessed to see in my whole life.

Автор: dried flowers poppy pods (не зарегистрирован), дата: 4 июня, 2023 - 17:22
#permalink

We are truly thankful for your blog entry. It's really fun to read. I enjoyed it a lot. dried flowers poppy pods Thanks for sharing this wonderful information.


Автор: buy og kush online (не зарегистрирован), дата: 6 июня, 2023 - 13:58
#permalink

Thank you for this great read. I am really thankful to you for giving me buy og kush online blog commenting sites. It has been useful.


Автор: MARIJUANA-PRODUCTS (не зарегистрирован), дата: 7 июня, 2023 - 16:31
#permalink

Took me time to read all the comments, but I really enjoyed the article. MARIJUANA-PRODUCTS I'll often be once again to read much more, thank you for that information.


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
1 + 17 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

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

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum