Storage

Курсоры

Такие методы как возвращают массив ключей/значений.

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

Тогда метод вернёт ошибку при попытке получить все записи в массиве.

Что делать?

Курсоры предоставляют возможности для работы в таких ситуациях.

Объект cursor идёт по хранилищу объектов с заданным запросом (query) и возвращает пары ключ/значение по очереди, а не все сразу. Это позволяет экономить память.

Так как хранилище объектов внутренне отсортировано по ключу, курсор проходит по хранилищу в порядке хранения ключей (по возрастанию по умолчанию).

Синтаксис:

  • ключ или диапазон ключей, как для .
  • необязательный аргумент, доступные значения:

    • – по умолчанию, курсор будет проходить от самого маленького ключа к большему.
    • – обратный порядок: от самого большого ключа к меньшему.
    • , – то же самое, но курсор пропускает записи с тем же ключом, что уже был (только для курсоров по индексам, например, для нескольких книг с price=5, будет возвращена только первая).

Основным отличием курсора является то, что генерируется многократно: один раз для каждого результата.

Вот пример того, как использовать курсор:

Основные методы курсора:

  • – продвинуть курсор на позиций, пропустив значения.
  • – продвинуть курсор к следующему значению в диапазоне соответствия (или до позиции сразу после ключа key, если указан).

Независимо от того, есть ли ещё значения, соответствующие курсору или нет – вызывается , затем в мы можем получить курсор, указывающий на следующую запись или равный .

В приведённом выше примере курсор был создан для хранилища объектов.

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

Для курсоров по индексам является ключом индекса (например price), нам следует использовать свойство как ключ объекта:

Configuration

setPrefix

You could set a prefix to avoid overwriting any local storage variables from the rest of your appDefault prefix:

myApp.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
    .setPrefix('yourAppName');
});

setStorageType

You could change web storage type to localStorage or sessionStorageDefault storage:

myApp.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
    .setStorageType('sessionStorage');
});

setDefaultToCookie

If localStorage is not supported, the library will default to cookies instead. This behavior can be disabled.Default:

myApp.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
    .setDefaultToCookie(false);
});

setStorageCookie

Set cookie options (usually in case of fallback)expiry: number of days before cookies expire (0 = session cookie). default: path: the web path the cookie represents. default: secure: whether to store cookies as secure. default:

myApp.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
    .setStorageCookie(45, '<path>', false);
});

setStorageCookieDomain

Set the cookie domain, since this runs inside a the block, only providers and constants can be injected. As a result, service can’t be used here, use a hardcoded string or .No default value

myApp.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
    .setStorageCookieDomain('<domain>');
});

For local testing (when you are testing on localhost) set the domain to an empty string ». Setting the domain to ‘localhost’ will not work on all browsers (eg. Chrome) since some browsers only allow you to set domain cookies for registry controlled domains, i.e. something ending in .com or so, but not IPs or intranet hostnames like localhost.

setNotify

Configure whether events should be broadcasted on $rootScope for each of the following actions:setItem , default: , event «LocalStorageModule.notification.setitem»removeItem , default: , event «LocalStorageModule.notification.removeitem»

myApp.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
    .setNotify(true, true);
});

Configuration Example

Using all together

myApp.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
    .setPrefix('myApp')
    .setStorageType('sessionStorage')
    .setNotify(true, true)
});

isSupported

Checks if the browser support the current storage type(e.g: , ).
Returns:

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  if(localStorageService.isSupported) {
    //...
  }
  //...
});

setPrefix

Change the local storage prefix during execution
Returns:

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  localStorageService.setPrefix('newPrefix');
  //...
});

getStorageType

Returns:

You can also dynamically change storage type by passing the storage type as the last parameter for any of the API calls. For example:

set

Directly adds a value to local storage.
If local storage is not supported, use cookies instead.Returns:

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  function submit(key, val) {
   return localStorageService.set(key, val);
  }
  //...
});

get

Directly get a value from local storage.
If local storage is not supported, use cookies instead.Returns:

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  function getItem(key) {
   return localStorageService.get(key);
  }
  //...
});

keys

Return array of keys for local storage, ignore keys that not owned.Returns:

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  var lsKeys = localStorageService.keys();
  //...
});

remove

Remove an item(s) from local storage by key.
If local storage is not supported, use cookies instead.Returns:

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  function removeItem(key) {
   return localStorageService.remove(key);
  }
  //...
  function removeItems(key1, key2, key3) {
   return localStorageService.remove(key1, key2, key3);
  }
});

clearAll

Remove all data for this app from local storage.
If local storage is not supported, use cookies instead.Note: Optionally takes a regular expression string and removes matching.Returns:

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  function clearNumbers(key) {
   return localStorageService.clearAll(^\d+$);
  }
  //...
  function clearAll() {
   return localStorageService.clearAll();
  }
});

bind

Bind $scope key to localStorageService.
Usage:
key: The corresponding key used in local storage
Returns: deregistration function for this listener.

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  localStorageService.set('property', 'oldValue');
  $scope.unbind = localStorageService.bind($scope, 'property');

  //Test Changes
  $scope.update = function(val) {
    $scope.property = val;
    $timeout(function() {
      alert("localStorage value: " + localStorageService.get('property'));
    });
  }
  //...
});
<div ng-controller="MainCtrl">
  <p>`property`</p>
  <input type="text" ng-model="lsValue"/>
  <button ng-click="update(lsValue)">update</button>
  <button ng-click="unbind()">unbind</button>
</div>

deriveKey

Return the derive key
Returns

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  localStorageService.set('property', 'oldValue');
  //Test Result
  console.log(localStorageService.deriveKey('property')); // ls.property
  //...
});

length

Return localStorageService.length, ignore keys that not owned.
Returns

myApp.controller('MainCtrl', function($scope, localStorageService) {
  //...
  var lsLength = localStorageService.length(); // e.g: 7
  //...
});

Overview #

This API has been optimized to meet the specific storage needs of extensions. It provides the same storage capabilities as the localStorage API with the following key differences:

  • User data can be automatically synced with Chrome sync (using ).
  • Your extension’s content scripts can directly access user data without the need for a background page.
  • A user’s extension settings can be persisted even when using split incognito behavior.
  • It’s asynchronous with bulk read and write operations, and therefore faster than the blocking and serial .
  • User data can be stored as objects (the stores data in strings).
  • Enterprise policies configured by the administrator for the extension can be read (using with a schema).

За пределами пары ключ/значение: конкурентное видение

Хотя в истории было много уловок и обходных путей, нынешнее состояние HTML5-хранилища на удивление благополучно. Новый API был стандартизирован и включен во все основные браузеры, платформы и устройства. Для веб-разработчика такое увидишь не каждый день, не так ли? Но это больше, чем «5 мегабайт пар ключ/значение» и будущее постоянного локального хранилища это… как бы сказать… ну, пусть конкурентное видение.

Одно видение является аббревиатурой, которую вы уже знаете — SQL. В 2007 году Google запустил Gears, кроссбраузерный плагин с открытым исходным кодом, в который включена встроенная база данных на основе SQLite. Этот ранний прототип позже повлиял на создание спецификации Web SQL Database. База данных Web SQL (ранее известная как «WebDB») обеспечивает тонкую оболочку вокруг базы данных SQL, что позволяет делать следующие вещи из JavaScript:

openDatabase(‘documents’, ‘1.0’, ‘Local document storage’, 5*1024*1024, function (db) {
  db.changeVersion(», ‘1.0’, function (t) {
    t.executeSql(‘CREATE TABLE docids (id, name)’);
  }, error);
});

Как вы можете видеть, большая часть действий находится в строке с методом ExecuteSQL. Эта строка может поддерживать любые команды SQL, в том числе SELECT, UPDATE, INSERT и DELETE. Это все равно, что серверное программирования баз данных, за исключением того, что вы делаете это с JavaScript! О радость!

Спецификация базы данных Web SQL была реализована в четырех браузерах и платформах.

Поддержка базы данных Web SQL
IE Firefox Safari Chrome Opera iPhone Android
4.0+ 4.0+ 10.5+ 3.0+ 2.0+

Конечно, если вы использовали более чем одну базу данных в своей жизни, то знаете, что «SQL» это скорее маркетинговый термин, чем жесткий и быстрый стандарт (кто-то может сказать то же самое об HTML5, но это не важно). Конечно, есть актуальная спецификация SQL (она называется SQL-92), но в мире нет сервера баз данных, который соответствует только этой спецификации

Есть Oracle SQL, Microsoft SQL, SQL в MySQL, SQL в PostgreSQL, SQL в SQLite. В действительности, каждый из этих продуктов с течением времени добавляет новые функции SQL, так что недостаточно даже произнести «SQL в SQLite». Вы должны сказать «версия SQL, который поставляется вместе с SQLite версии X.Y.Z».

Все это подводит нас к следующей оговорке, в настоящее время размещенной вверху спецификации Web SQL.

Именно на этом фоне я расскажу вам о другом конкурентном видении для продвинутых, постоянное локальное хранилище для веб-приложений: Indexed Database API, ранее известное как «WebSimpleDB», теперь ласково называемое IndexedDB.

Indexed Database API предоставляет то, что называется хранилище объектов, при этом много идей заимствовано из баз данных SQL. Есть «базы данных» с «записями», каждая запись имеет определенное количество «полей». У каждого поля есть определенный тип данных, который определяется при создании базы данных. Вы можете выбрать часть записей, затем перечислить их «курсором». Изменения в хранилище объектов обрабатываются с «транзакциями».

Если вы хоть раз программировали базы данных SQL, то эти термины, вероятно, вам знакомы. Основная разница в том, что хранилище объектов не имеет структурированного языка запросов. Вы не напишите условие вроде «SELECT * from USERS where ACTIVE = ‘Y'». Вместо этого используются методы, предоставляемые хранилищем объектов для открытия базы USERS, перечисления записей, фильтрации наших записей и использование методов доступа для получения значения каждого поля оставшихся записей. An early walk-through of IndexedDB (Ранний проход IndexedDB) это хорошее руководство о том, как работает IndexedDB и сравнение IndexedDB с Web SQL.

На момент написания IndexedDB был реализован только в бета-версии Firefox 4. Для контраста, Mozilla заявила, что никогда не будет воплощать Web SQL. Google заявил, что они рассматривают поддержку IndexedDB для Chromium и Google Chrome. И даже Майкрософт заявил, что IndexedDB «отличное решение для веб».

Что вы как веб-разработчик можете делать с IndexedDB? На данный момент практически ничего, кроме некоторых технологических демонстраций. Через год? Возможно.

Overview of web storage

Web storage is data stored locally in a user’s browser. There are two types of web storage:

  • Local storage — data with no expiration date that will persist after the browser window is closed.
  • Session storage — data that gets cleared after the browser window is closed.

This is useful for saving data such as user preferences (light or dark color theme on a website), remembering shopping cart items, or remembering a user is logged into a website.

Previously, cookies were the only option for remembering this type of local, temporary data. Local storage has a significantly higher storage limit (5MB vs 4KB) and doesn’t get sent with every HTTP request, so it can be a better option for client-side storage.

Here is an overview of methods.

Method Description
Add key and value to local storage
Retrieve a value by the key
Remove an item by key
Clear all storage

You can test out what’s in local storage by going to the JavaScript console and typing it in. Actually do this, don’t just read it.

Adding some data to is as easy as using the method. I’ll use a generic key and value for the names, but they can be any strings.

Now if you test in the console again, you’ll find your new key and value.

If you want to get the value for a particular key, you’ll use the method.

Finally, you can remove the data with .

Using will clear all local storage.

Now we can begin setting up the app.

Usage

unless localStorage?{LocalStorage} =require('')localStorage =newLocalStorage('./scratch')localStorage.setItem('myFirstKey', 'myFirstValue')console.log(localStorage.getItem('myFirstKey'))localStorage._deleteLocation()

Open or create and add these two lines:

// /src/setupTests.jsimport { LocalStorage } from "node-localstorage";global.localStorage = new LocalStorage('./scratch');
if (typeof localStorage === "undefined" || localStorage === null) {  var LocalStorage = require('node-localstorage').LocalStorage;  localStorage = new LocalStorage('./scratch');}localStorage.setItem('myFirstKey', 'myFirstValue');console.log(localStorage.getItem('myFirstKey'));

Polyfil your node.js environment with this as the global localStorage when launching your own code

node -r node-localstorage/register my-code.js

Слежение за областью HTML5-хранилища

Если вы хотите программно отслеживать изменения хранилища, то должны отлавливать событие storage. Это событие возникает в объекте window, когда setItem(), removeItem() или clear() вызываются и что-то изменяют. Например, если вы установили существующее значение или вызвали clear() когда нет ключей, то событие не сработает, потому что область хранения на самом деле не изменилась.

Событие storage поддерживается везде, где работает объект localStorage, включая Internet Explorer 8. IE 8 не поддерживает стандарт W3C addEventListener (хотя он, наконец-то, будет добавлен в IE 9), поэтому, чтобы отловить событие storage нужно проверить, какой механизм событий поддерживает браузер (если вы уже проделывали это раньше с другими событиями, то можете пропустить этот раздел до конца). Перехват события storage работает так же, как и перехват других событий. Если вы предпочитаете использовать jQuery или какую-либо другую библиотеку JavaScript для регистрации обработчиков событий, то можете проделать это и со storage тоже.

if (window.addEventListener) {
  window.addEventListener(«storage», handle_storage, false);
} else {
  window.attachEvent(«onstorage», handle_storage);
};

Функция обратного вызова handle_storage будет вызвана с объектом StorageEvent, за исключением Internet Explorer, где события хранятся в window.event.

function handle_storage(e) {
  if (!e) { e = window.event; }
}

В данном случае переменная e будет объектом StorageEvent, который обладает следующими полезными свойствами.

Объект StorageEvent
Свойство Тип Описание
key string Ключ может быть добавлен, удален или изменен.
oldValue любой Предыдущее значение (если переписано) или null, если добавлено новое значение.
newValue любой Новое значение или null, если удалено.
url* string Страница, которая вызывает метод, приведший к изменению.

* Примечание: свойство url изначально называлось uri и некоторые браузеры поддерживали это свойство перед изменением спецификации. Для обеспечения максимальной совместимости вы должны проверить существует ли свойство url, и если нет проверить вместо него свойство uri.

Событие storage нельзя отменить, внутри функции обратного вызова handle_storage нет возможности остановить изменение. Это просто способ браузеру сказать вам: «Эй, это только что случилось. Вы ничего не можете сделать, я просто хотел, чтобы вы знали».

The JavaScript localStorage object

HTML5 specification introduces the as a way to store data with no expiration date in the web browsers.

In other words, the data stored in the browsers will persist even after you close the browser windows.

The data stored in the is bound to an origin. It means that the is unique per .

localStorage vs. cookies

First, the data stored in the isn’t sent to the server in every request like cookies. For this reason, you can store more data in the .

Most modern web browsers allow you to store up to 5MB of data in the . Note that you can store up to 4KB in cookies.

Second, the data stored in the can be managed by the client, specifically JavaScript in the web browser. It cannot be accessible by the servers.

However, cookies can be managed by both JavaScript in web browsers and servers.

Accessing the localStorage

You can access the via the property of the object:

Since the is an instance of the type, you can invoke the methods of the type to manage data.

When you type the following code in the Console:

… you’lll see the following object:

1) The setItem() method

The following uses the method to store a name-value pair in the :

2) The length property

To get the number of name-value pairs, you use the property like this:

Since the object is global, you don’t need to explicitly specify it. For example:

3) The getItem() method

To get the value by a key, you use the method. The following example uses the method to get the value of key:

4) The removeItem() method

To remove a name-value pair by a key, you use the method. For example:

5) Loop over keys of the localStorage object

The following stores three name-value pairs to the :

To iterate over name-value pairs stored in the , you use the method with loop:

Output:

What is the Web Storage API?

The Web Storage API is a set of mechanisms that enable browsers to store key-value pairs. It is designed to be much more intuitive than using cookies.

The key-value pairs represent storage objects, which are similar to objects except they remain intact during page loads, and are always strings. You can access these values like an object or using the method (more on that later).

What is the difference between and ?

The Web Storage API consists of two mechanisms: and . Both and maintain a separate storage area for each available origin for the duration of the page session.

The main difference between and is that only maintains a storage area while the browser is open (including when the page reloads or restores) while continues to store data after the browser is closed. In other words, whereas data stored in is cleared when the page is closed, data stored in does not expire.

In this tutorial, we’ll focus on how to use in JavaScript.

Краткая история локального хранилища до HTML5

Вначале был только один Internet Explorer. По крайней мере, Майкрософт хотел, чтобы мир так думал. С этой целью в рамках Первой Великой Войны браузеров Майкрософт изобрел очень много вещей и включил их в свой браузер-который-завершил-войну — Internet Explorer. Одна из этих вещей была названа DHTML Behaviors, а одна из форм поведения называется userData.

UserData позволяет веб-странице хранить до 64 Кб данных на каждый домен в иерархической XML-подобной структуре. Доверенные домены, такие как интранет-сайты могут хранить в десять раз больше. И эй, 640 Кб должно быть достаточно для всех. IE не представил какой-либо способ изменить эти соглашения, поэтому нет способа увеличить объем доступной памяти.

В 2007 году Google запустила Gears, открытый плагин для браузера направленный на обеспечение дополнительных возможностей. Мы уже обсуждали Gears ранее в контексте обеспечения геолокации в Internet Explorer. Gears предоставляет API для встроенной базы данных на основе SQLite. После получения единственного разрешения от пользователя, Gears может хранить неограниченное количество данных для каждого домена в таблицах базы данных SQL.

В то же время Брэд Нойберг и другие продолжали вкалывать на dojox.storage чтобы обеспечить единый интерфейс для всех этих разных плагинов и API. На 2009 год dojox.storage может автоматически определить (и обеспечить универсальный интерфейс) Adobe Flash, Gears, Adobe AIR и ранний прототип хранилища HTML5, который был реализован только в старых версиях Firefox.

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

The localStorage Object

The localStorage object stores the data with no expiration date. The data
will not be deleted when the browser is closed, and will be available the next day, week, or year.

Example

// StorelocalStorage.setItem(«lastname», «Smith»);// Retrieve
document.getElementById(«result»).innerHTML = localStorage.getItem(«lastname»);

Example explained:

  • Create a localStorage name/value pair with name=»lastname» and value=»Smith»
  • Retrieve the value of «lastname» and insert it into the element with id=»result»

The example above could also be written like this:

// StorelocalStorage.lastname = «Smith»;// Retrieve
document.getElementById(«result»).innerHTML = localStorage.lastname;

The syntax for removing the «lastname» localStorage item is as follows:

localStorage.removeItem(«lastname»);

Note: Name/value pairs are always stored as strings.
Remember to convert them to another format when needed!

The following example counts the number of times a user has clicked a button.
In this code the value string is converted to a number to be able to increase the counter:

Example

if (localStorage.clickcount) {  localStorage.clickcount = Number(localStorage.clickcount) + 1;
} else {  localStorage.clickcount = 1;}
document.getElementById(«result»).innerHTML = «You have clicked the button » +
localStorage.clickcount + » time(s).»;

Приватный просмотр (режим инкогнито)

Большинство современных браузеров поддерживают опцию конфиденциальности «инкогнито», «приватный просмотр», или что-то подобное, что не хранит такие данные, как история и файлы cookie. Это принципиально несовместимо с веб-хранилищем по очевидным причинам, по этой причине поставщики браузеров экспериментируют с различными сценариями устранения этой несовместимости.

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

Разработчики должны знать об этих различных реализациях и учитывать их при разработке веб-сайтов в зависимости от API веб-хранилища.

Storages

Store.js will pick the best available storage, and automatically falls back to the first available storage that works:

List of all Storages

  • all.js All the storages in one handy place.
  • localStorage.js Store values in localStorage. Great for all modern browsers.
  • sessionStorage.js Store values in sessionStorage.
  • cookieStorage.js Store values in cookies. Useful for Safari Private mode.
  • memoryStorage.js Store values in memory. Great fallback to ensure store functionality at all times.
  • oldFF-globalStorage.js Store values in globalStorage. Only useful for legacy Firefox 3+.
  • oldIE-userDataStorage.js Store values in userData. Only useful for legacy IE 6+.

Storages limits

Each storage has different limits, restrictions and overflow behavior on different browser. For example, Android has has a 4.57M localStorage limit in 4.0, a 2.49M limit in 4.1, and a 4.98M limit in 4.2… Yeah.

To simplify things we provide these recommendations to ensure cross browser behavior:

Storage Targets Recommendations More info
all All browsers Store < 1 million characters (Except Safari Private mode)
all All & Private mode Store < 32 thousand characters (Including Safari Private mode)
localStorage Modern browsers Max 2mb (~1M chars)
sessionStorage Modern browsers Max 5mb (~2M chars)
cookieStorage Safari Private mode Max 4kb (~2K chars)
userDataStorage IE5, IE6 & IE7 Max 64kb (~32K chars)
globalStorage Firefox 2-5 Max 5mb (~2M chars)
memoryStorage All browsers, fallback Does not persist across pages!

Write your own Storage

Chances are you won’t ever need another storage. But if you do…

See storages/ for examples. Two good examples are memoryStorage and localStorage.

Basically, you just need an object that looks like this:

// Example custom storage
var storage = {
	name: 'myStorage',
	read: function(key) { ... },
	write: function(key, value) { ... },
	each: function(fn) { ... },
	remove: function(key) { ... },
	clearAll: function() { ... }
}
var store = require('store').createStore(storage)
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector