Опубликован: 16.06.2010 | Уровень: специалист | Доступ: платный
Лекция 7:

Технологии будущего

6.8.4. WHATWG DB Backend (openDatabase)


Рабочая группа WHATWG была организована производителями браузеров Apple, Mozilla Foundation и Opera Software ASA. Именно эта группа создала документ Web Application 1.0, который лег в основу пятой версии HTML.

В частности, этот документ решал и проблему хранения данных веб-приложения на стороне пользователя. Текущая спецификация HTML5 решает эту проблему иначе, а метод, предложенный данной группой, был реализован в одной из версий движка WebKit.

Некоторые версии браузеров, основанных на WebKit — Safari (в том числе под iPhone) и Chromium также содержат openDatabase (именно так называется эта часть спецификации) и представляют собой несложный доступ к реляционной СУБД SQLite из JavaScript. Кроме того, поддержка openDatabase появилась в "Опере" 10.50.

Максимальный размер такого хранилища теоретически ограничен лишь местом на диске и внутренними ограничениями SQLite, но по умолчанию Safari устанавливает предел в 5 Мб.

Упрощенный (с минимальной обработкой ошибок) класс для доступа к openDatabase выглядит так:

function SafariStorage(name, maxsize) {
  this.db = null;
  if (!window.openDatabase) return;
  try {
    this.db = openDatabase(name, '1.0 ', 'Storage for ' + 
    name, maxsize); // maxsize — в байтах
  } catch (e) {
    this.db = null;
    return;
}
this.db.transaction(function (t) {
  t.executeSql('CREATE TABLE IF NOT EXISTS storage(k TEXT 
  UNIQUE NOT NULL PRIMARY KEY, v TEXT NOT NULL);', []);
})
  this.get = function (name, fn, scope) {
    scope = scope || this;
    this.db.transaction(function (t) {
      t.executeSql('SELECT v FROM storage WHERE k = ? '
      [name], function (t, r) {
        if (r.rows.length) {
          fn.call(scope, r.rows.item(0)['v'])
        } else {
          fn.call(scope, null)
        }
      });
  });

}
this.set = function (name, value) {
  this.db.transaction(function (t) {
    t.executeSql('INSERT OR REPLACE INTO storage(k, v) 
    VALUES (?, ?)', [name, value]);
  });
}
this.del = function (name) {
  this.db.transaction(function (t) {
    t.executeSql('DELETE FROM storage WHERE k = ?', 
    [name]);
    });
  }
}
}

Метод transaction создает транзакцию и передает ее своему аргумен ту — функции, запрос внутри который будет обработан в единой транзакции. У transaction есть еще два аргумента — функции, первая из которых будет вызвана, если транзакция выполнена успешно, вторая — если закончилась ошибкой, объект ошибки будет первым аргументом вызываемой функции.

У executeSql (обратите внимание на регистр букв!) также есть опциональные аргументы: после текста запроса и его подстановок можно указать callback для возвращаемых данных и функцию, которая будет вызвана в случае ошибки, с двумя аргументами: транзакцией и объектом ошибки.

6.8.5. globalStorage и localStorage

Спецификация на globalStorage присутствует в ранних версиях черновика HTML5, откуда ее удалили из соображений безопасности. Основная идея globalStorage — дать разработчикам возможность обращаться к данным поддоменов, как это сделано в cookie.

Этот вид хранилища был реализован в Firefox 2 (и в Internet Explorer 8.0 beta 1), но уже в следующей версии браузера возможность обращаться к данным поддоменов отключили. В такой "урезанной" версии globalStorage по возможностям эквивалентно хранилищу localStorage, которое заняло в HTML5 нишу своего небезопасного предшественника.

В настоящий момент localStorage поддерживается браузерами FireFox 3.5 и выше, Internet Explorer 8.0 (с версии beta 2), Safari 4.0 и выше, а так же Opera 10.50 и выше.

Ограничения, накладываемые на размер хранилища, устанавливаются разными производителями браузеров по-разному, так, в Firefox это 5 Мб, а в IE 8 — 10 миллионов байт (причем, учитывается место, занятое не только значениями, но и именами ключей). Другое ограничение накладывается на имена ключей, в частности, в них не может быть пробелов.

function HTML5Storage() {
  if (window.localStorage) {
    this.storage = window.localStorage } else if (window.globalStorage) {
  this.storage = window.globalStorage[location.hostname J ||  'localhost.localdomain '] }   else {
    return false
  }
    this.get = function (name) {
    var out = this.storage.getItem(name); return out && out.value ? out.value : out;
  }
    this.set = function (name, value) { this.storage.setItem(name, value);
  }
    this.del = function (name) {
    this.storage.removeItem(name)
  }
}

6.8.6. Google Gears

Последнее из рассматриваемых нами хранилищ — GoogLe Gears, расширение для браузеров, придуманное GoogLe. В настоящее время встроено в браузер GoogLe Chrome, для других поддерживаемых браузеров скачивается и устанавливается отдельно. Диапазон поддерживаемых браузеров довольно широк: Firefox начиная с версии 1.5, Internet ExpLorer 6.0 и выше, Safari 3.1.1 и выше (для Mac OS), а также мобильные браузеры — IE MobiLe с версии 4.01 и Opera MobiLe 9.51 и выше.

Основная идея хранилища GoogLe Gears та же, что и у openDatabase, тот же самый доступ к SQLite, но с несколько другим API:

function GearsStorage(name) {
  if (Iwindow.google || Iwindow.google.gears) { var factory = null; // Firefox
      if (typeof GearsFactory I= 'undefined') {
        factory = new GearsFactory(); } else { // IE try {
      factory = new ActiveXObject('Gears.Factory'); if (factory.getBuildInfo().indexOf('ie_mobile') I= -1) {
    factory.privateSetGlobalObject(this);
  }
} catch (e) { // Safari
    if ((typeof navigator.mimeTypes I= 'undefined') && navigator.mimeTypes["application/ J x-googlegears"]) 
    {
        factory = document.createElement("object"); factory.style.display = "none"; factory.width = 0; factory.height = 0;
        factory.type = "application/x-googlegears"; document.documentElement.appendChild(factory);
    }
        }
          if (Ifactory) return; if (Iwindow.google) { google = {};
        }
      if (Igoogle.gears) {
          google.gears = {factory: factory};
        }
      }
        this._begin = function () {
        this.db.execute('BEGIN').close();
        }
        this._commit = function () {
        this.db. execute('COMMIT').close();
}

Как видно, существенную часть занимает инициализация Google Gears, в каждом браузере она выполняется по-разному. API устроено проще, чем в openDatabase — транзакции нужно создавать самостоятельно, зато есть возможность возвращать данные непосредственно, не прибегая к callback.

Авторы не обладают сведениями об ограничениях на размер этого хранилища, вполне может быть, что никаких ограничений, помимо тех, что есть в самом SQLite, не существует.

6.8.7. Библиотеки для работы с клиентскими хранилищами

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

PersistJS (http://pablotron.org/?cid=1557 ) — пожалуй, наиболее известная библиотека на этом поприще. Она поддерживает все перечисленные виды хранилищ (правда, Google Gears для IE не поддерживается), но, несмотря на свою известность, обладает рядом существенных недостатков.

Первый недостаток — нет возможности изменить последовательность, в которой PersistJS перебирает методики хранения данных. К примеру, если вы решили поставить localStorage выше Google Gears, а cookie исключить, вам придется вмешиваться в код библиотеки.

Другая проблема — если библиотека обнаружила, например, хранилище Google Gears, а клиент ответил отказом на запрос разрешения хранения данных, то PersistJS останется в неопределенном положении.

Еще недоработка — PersistJS не проверяет готовность Flash-ролика, и в том случае, если вы используете это хранилище, есть небольшая вероятность того, что ваш код попытается обратиться к данным еще до того, как ролик будет загружен. Другая связанная с Flash-роликом проблема — библиотека не умеет запрашивать дополнительное место для хранения данных, если 100 Кб, которые можно использовать без запроса разрешения, исчерпаны.

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

Впрочем, у библиотеки хороший плюс — небольшой (около 9 Кб) размер.

Dojo (http://www.dojotoolkit.org/ ) поддерживает хранилища Flash, Google Gears, globalStorage (Firefox 2.0) и среду запуска веб-приложений Adobe AIR.

Этот фреймворк лишен недостатков PersistJS, но есть изъян — гигантский размер: версия 1.3.2 занимает 45 Мб. Конечно, для работы с хранилищем весь фреймворк не нужен, но даже минимально необходимый набор занимает более 100 Кб.

Существует адаптированная версия Dojo Storage, которая называется SRAX Storage (http://fullajax.ru/#:download/), но она поддерживает только Flash Local Shared Object.

jStore (http://code.google.com/p/jquery-jstore/) — небольшой плагин к jQuery, который поддерживает все рассмотренные хранилища, кроме cookie, обладает умеренным размером (около 15 Кб в минимизированном виде) и свободен от недостатков PersistJS.

6.8.8. Резюме

К сожалению, даже создатели HTML5 не предусмотрели возможности адресации к хранилищу посредством URL. Было бы очень удобно, положив в хранилище JavaScript или графическое изображение, подключить содержимое через обычный тег HTML 1 .

Необходимо помнить, что хранилище — клиентское, и данные, сохраненные в хранилище, не будут доступны клиенту на другой машине и даже (увы) в другом браузере. Так что наиболее подходящее использование клиентских хранилищ — кэширование текстовых данных: JavaScript, CSS,

Хранилище Ограничение Браузеры
userData behavior Интранет — 512 Кб каждая запись, 10 Мб на домен, ограниченные узлы — 64 Кб / 640 Кб, остальные — 128 Кб / 1Мб IE 5.0+
gLobaLStorage 5 Мб FF 2.0+, IE 8 beta 1
LocaLStorage Firefox, Safari, Opera — 5 Мб Internet ExpLorer — 10 MiB FF 3.5+, Safari 4+, IE 8 beta 2+, Opera 10.50+
openDatabase 5 Мб Opera 10.50+, некоторые версии Safari 3.xx, 4.xx, GoogLe Chrome 3.xx, 4.xx
GoogLe Gears Запрашивает разрешение на использование, ограничений по размеру нет Встроен в GoogLe Chrome, плагины для IE 6+, Opera MobiLe 9.51+, FF 1.5+, IE MobiLe 4.01+, Safari 3.1.1+
FLash Запрашивает разрешение на хранение более 100 Кб данных, ограничений по размеру нет Плагины для IE, FF, GoogLe Chrome, Safari

1 - создатели GoogLe Gears озаботились доступом к бинарным данным из своего хранилища, изображениями можно манипулировать и выводить в окно браузера при помощи специального расширения, используя тег Canvas. а значит, данных о состоянии приложения и его редко изменяемых ресурсов, которые выгоднее хранить на стороне пользователя. Принцип использования прост: проверяется наличие нужного ресурса в хранилище; если ресурс обнаружен, он загружается из хранилища, если нет, с сервера (например, при помощи AJAX) и сохраняется в хранилище. Далее соответствующий тег с полученным содержимым создается в DOM. К сожалению, браузер Opera не предоставляет никакого встроенного хранилища, хотя в нем можно использовать Flash Local Shared Object; зато современные версии остальных браузеров не нуждаются в установке каких-либо дополнительных плагинов. Всеми браузерами без исключения поддерживаются cookie, но их вряд ли можно рекомендовать в качестве клиентского хранилища из-за сильных ограничений на размер и увеличения исходящего трафика. Из всех рассмотренных библиотек для доступа к хранилищам оптимальнее, на наш взгляд, использовать библиотеку jStore: она достаточно гибкая, небольшого размера и поддерживает все основные виды хранилищ.

Ольга Артёмова
Ольга Артёмова

Доброго времени суток!

Прошла курс, но почему-то диплом получить не могу, хотя курс значится завершенным, хотя обязательные два модуля пройдены. Как решить эту проблему?

Сертификация: оптимизация и продвижение web-сайтов.

Ярославй Грива
Ярославй Грива
Россия, г. Санкт-Петербург
Ёдгор Латипов
Ёдгор Латипов
Таджикистан, Кургантепа