Как работать с localstorage в javascript

Changelog

  • 2.1.7 — 2020-06-08 — Fixed stringifying null and undefined (thanks @gamesaucer)
  • 2.1.6 — 2020-04-10 — Fix backward compatibility bug (thanks @WillBartee)
  • 2.1.5 — 2019-12-02 — Fixed empty string key(n) return (@appy-one, thanks for reporting)
  • 2.1.2 thru 2.1.4 — 2019-11-17 — Upgrading and testing npm publish scripts
  • 2.1.1 — 2019-11-17 — npm publish cleanup
  • 2.1.0 — 2019-11-17 — Added back dot-property and associative-array syntax using ES6 Proxy
  • 2.0.0 — 2019-11-17 — Updated all the depdendencies, added ability to register as polyfill (thanks @dy)
  • 1.3.1 — 2018-03-19 — Resolves issue #32 (thanks, plamens)
  • 1.3.0 — 2016-04-09 — Possibly backward breaking if you were using experimental syntax Reverted experimental
    associative array and dot-property syntax. The API for Proxy changed with node.js v6.x which broke it. Then when
    I switched to the new syntax, it broke the EventEmitter functionality. Will restore once I know how to fix that.
  • 1.2.0 — 2016-04-09 — Atomic writes (thanks, mvayngrib)
  • 1.1.2 — 2016-01-08 — Resolves issue #17 (thanks, evilaliv3)
  • 1.1.1 — 2016-01-04 — Smarter associative array and dot-property syntax support
  • 1.1.0 — 2016-01-03 — Backward breaking if you used any of the non-standard methods. They are now all preceded with
    an underscore. Big upgrade for this version is experimental support for associative array and dot-property syntax.
  • 1.0.0 — 2016-01-03 — Fixed bug with empty string key (thanks, tinybike)
  • 0.6.0 — 2015-09-11 — Removed references to deprecated fs.existsSync() (thanks, josephbosire)
  • 0.5.2 — 2015-08-01 — Fixed defect where keys were not being updated correctly by removeItem() (thanks, ed69140)
  • 0.5.1 — 2015-06-01 — Added support for events
  • 0.5.0 — 2015-02-02 — Added JSONStorage class which allows you set and get native JSON
  • 0.4.1 — 2015-02-02 — More robust publishing/tagging (like Lumenize)
  • 0.4.0 — 2015-02-02 — Uses more efficient fs.statSync to set initial size (thanks, sudheer594)
  • 0.3.6 — 2014-12-24 — Allows usage without
  • 0.3.5 — 2014-12-23 — Fixed toString() for QuotaExceededError
  • 0.3.4 — 2013-07-07 — Moved CoffeeScript to devDependencies
  • 0.3.3 — 2013-04-05 — Added support for ‘/’ in keys by escaping before creating file names
  • 0.3.2 — 2013-01-19 — Renamed QuotaExceededError to QUOTA_EXCEEDED_ERR to match most browsers
  • 0.3.1 — 2013-01-19 — Fixed bug where it threw plain old Error instead of new QuotaExceededError
  • 0.3.0 — 2013-01-19 — Added QuotaExceededError support
  • 0.2.0 — 2013-01-03 — Added quota support
  • 0.1.2 — 2012-11-02 — Finally got Travis CI working
  • 0.1.1 — 2012-10-29 — Update to support Travis CI
  • 0.1.0 — 2012-10-29 — Original version

Examples #

If you’re interested in tracking changes made to a data object, you can add a listener to its event. Whenever anything changes in storage, that event fires. Here’s sample code to listen for saved changes:

We can take this idea even further. In this example we have an options page that allows the user to toggle a «debug mode» in the extension (implementation not shown here). Changes to this setting are immediately saved to sync storage by the options page and the background script uses to apply the setting as soon as possible.

Since service workers are not always running, Manifest V3 extensions sometimes need to asynchronously load data from storage before they execute their event handlers. To do this, the below snippet uses an async event handler that waits for the global to be populated before executing its logic.

Веб-хранилище. Назначение localStorage и sessionStorage

Веб-хранилище — это данные, хранящиеся локально в браузере пользователя. Существует 2 типа веб-хранилищ:

  • LocalStorage;
  • SessionStorage.

В них вы можете хранить информацию в формате ключ-значение. Ключ и значение – это всегда строки.

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

Отличие между этими хранилищами сводится только к периоду времени, в течение которого они могут хранить данные, помещенные в них:

  • SessionStorage – выполняет это в течение определённого промежутка времени (сессии). Закрытие вкладки или браузера приводит их к удалению. При этом данные в SessionStorage сохраняются при обновлении страницы.
  • LocalStorage – осуществляет это в течение неограниченного времени. Они сохраняются при перезагрузке браузера и компьютера. Их длительность хранения ничем не ограничена. Но, хоть эти данные могут храниться бесконечно в браузере, обычный пользователь может их очень просто удалить, например выполнив очистку истории (при включенной опции «файлы cookie и другие данные сайтов»).

Хранилище LocalStorage похоже на cookies. Оно также применяется для хранения данных на компьютере пользователя (в браузере). Но кроме общих сходств имеется также и много отличий.

Cookies vs. LocalStorage: В чём разница

Отличия между cookies и LocalStorage:

  • по месту хранения (куки и данные LocalStorage хранятся на компьютере пользователя в браузере);
  • по размеру (cookies ограничены 4 Кбайт, а размер LocalStorage — 5 Мбайт);
  • по включению этих данных в HTTP-заголовок (куки в отличие от данных локального хранилища включаются в состав запроса при отправке его на сервер, а также сервер их может добавлять в ответ при отправке его клиенту; таким образом cookies являются частью HTTP-протокола, и увеличивают объём передаваемых данных от клиента серверу и обратно);
  • по доступности данных (печеньки можно прочитать и установить как на сервере, так и на клиенте; на клиенте доступны все куки, кроме тех, у которых установлен флаг ; LocalStorage доступны только в браузере посредством JavaScript API);
  • по времени хранения данных (куки хранятся ограниченное время (до конца сеанса или истечения указанной даты), нахождение данных в локальном хранилище не ограничено по времени);
  • по удобству использования в JavaScript (работа с LocalStorage в JavaScript организовано намного удобнее чем с cookies);
  • по необходимости информирования пользователей Евросоюза (при использовании cookies сайт в ЕС должен получать на это разрешение от пользователей; для данных локального хранилища это не требуется);
  • по назначению (куки в основном используются для управления сеансом, персонализации и отслеживания действий пользователя, в то время как LocalStorage применяется в качестве обычного локального хранилища информации на компьютере пользователя).

Что использовать: LocalStorage или cookies? На самом деле, ответ на этот вопрос очень прост. Если вам не нужно отправлять данные с каждым HTTP-запросом на сервер, то в этом случае лучше использовать для хранения данных LocalStorage.

Безопасность данных

Хранилище LocalStorage привязана к источнику (домену, протоколу и порту). Данные, находящиеся в некотором источнике, доступны для всех сценариев страниц этого же источника. Из сценария, находящегося в одном источнике, нельзя получить доступ к данным, определяемым другим источником.

Хранилище SessionStorage ограничена только одной вкладкой браузера. Это означает, что в сценарии, находящемся в одной вкладке, нельзя получить информацию из сессионного хранилища другой вкладки даже у них одинаковые источники.

Итоги

Основные характеристики LocalStorage и SessionStorage:

  • данные хранятся в виде пар «ключ-значение»;
  • хранить можно только строки;
  • если вам необходимо хранить в этих хранилищах массивы и объекты, то сначала вы должны их превратить в строки, например, используя метод . Для преобразования строки обратно в массив или объект, можно использовать . Подробнее об этом позже.

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)

sessionStorage

The object is used much less often than .

Properties and methods are the same, but it’s much more limited:

  • The exists only within the current browser tab.
    • Another tab with the same page will have a different storage.
    • But it is shared between iframes in the same tab (assuming they come from the same origin).
  • The data survives page refresh, but not closing/opening the tab.

Let’s see that in action.

Run this code…

…Then refresh the page. Now you can still get the data:

…But if you open the same page in another tab, and try again there, the code above returns , meaning “nothing found”.

That’s exactly because is bound not only to the origin, but also to the browser tab. For that reason, is used sparingly.

Properties

local

Items in the storage area are local to each machine.

Properties

QUOTA_BYTES
number 5242880

The maximum amount (in bytes) of data that can be stored in local storage, as measured by the JSON stringification of every value plus every key’s length. This value will be ignored if the extension has the unlimitedStorage permission. Updates that would cause this limit to be exceeded fail immediately and set runtime.lastError.

managed

Items in the storage area are set by the domain administrator, and are read-only for the extension; trying to modify this namespace results in an error.

Properties

  • MAX_ITEMS
    number 512

    The maximum number of items that can be stored in sync storage. Updates that would cause this limit to be exceeded will fail immediately and set .

  • MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE
    number 1000000

    Deprecated since Chrome 40. The storage.sync API no longer has a sustained write operation quota.

  • MAX_WRITE_OPERATIONS_PER_HOUR
    number 1800

    The maximum number of , , or operations that can be performed each hour. This is 1 every 2 seconds, a lower ceiling than the short term higher writes-per-minute limit.

    Updates that would cause this limit to be exceeded fail immediately and set .

  • MAX_WRITE_OPERATIONS_PER_MINUTE
    number 120

    Since Chrome 40.

    The maximum number of , , or operations that can be performed each minute. This is 2 per second, providing higher throughput than writes-per-hour over a shorter period of time.

    Updates that would cause this limit to be exceeded fail immediately and set .

  • QUOTA_BYTES
    number 102400

    The maximum total amount (in bytes) of data that can be stored in sync storage, as measured by the JSON stringification of every value plus every key’s length. Updates that would cause this limit to be exceeded fail immediately and set .

  • QUOTA_BYTES_PER_ITEM
    number 8192

    The maximum size (in bytes) of each individual item in sync storage, as measured by the JSON stringification of its value plus its key length. Updates containing items larger than this limit will fail immediately and set .

Хранилище объектов

Чтобы сохранить что-то в IndexedDB, нам нужно хранилище объектов.

Хранилище объектов – это основная концепция IndexedDB. В других базах данных это «таблицы» или «коллекции». Здесь хранятся данные. В базе данных может быть множество хранилищ: одно для пользователей, другое для товаров и так далее.

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

Мы можем хранить почти любое значение, в том числе сложные объекты.

IndexedDB использует для клонирования и хранения объекта. Это как , но более мощный, способный хранить гораздо больше типов данных.

Пример объекта, который нельзя сохранить: объект с циклическими ссылками. Такие объекты не сериализуемы. также выдаст ошибку при сериализации.

Каждому значению в хранилище должен соответствовать уникальный ключ.

Ключ должен быть одним из следующих типов: number, date, string, binary или array. Это уникальный идентификатор: по ключу мы можем искать/удалять/обновлять значения.

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

Но для начала нужно создать хранилище.

Синтаксис для создания хранилища объектов:

Обратите внимание, что операция является синхронной, использование не требуется

  • – это название хранилища, например для книг,
  • – это необязательный объект с одним или двумя свойствами:

    • – путь к свойству объекта, которое IndexedDB будет использовать в качестве ключа, например .
    • – если , то ключ будет формироваться автоматически для новых объектов, как постоянно увеличивающееся число.

Если при создании хранилища не указать , то нам потребуется явно указать ключ позже, при сохранении объекта.

Например, это хранилище объектов использует свойство как ключ:

Хранилище объектов можно создавать/изменять только при обновлении версии базы данных в обработчике .

Это техническое ограничение. Вне обработчика мы сможем добавлять/удалять/обновлять данные, но хранилища объектов могут быть созданы/удалены/изменены только во время обновления версии базы данных.

Для обновления версии базы есть два основных подхода:

  1. Мы можем реализовать функции обновления по версиям: с 1 на 2, с 2 на 3 и т.д. Потом в сравнить версии (например, была 2, сейчас 4) и запустить операции обновления для каждой промежуточной версии (2 на 3, затем 3 на 4).
  2. Или мы можем взять список существующих хранилищ объектов, используя . Этот объект является , в нём есть метод , используя который можно проверить существование хранилища. Посмотреть, какие хранилища есть и создать те, которых нет.

Для простых баз данных второй подход может быть проще и предпочтительнее.

Вот демонстрация второго способа:

Чтобы удалить хранилище объектов:

Слежение за областью 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 нет возможности остановить изменение. Это просто способ браузеру сказать вам: «Эй, это только что случилось. Вы ничего не можете сделать, я просто хотел, чтобы вы знали».

JavaScript

JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()

JS Boolean
constructor
prototype
toString()
valueOf()

JS Classes
constructor()
extends
static
super

JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()

JS Error
name
message

JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()

JS JSON
parse()
stringify()

JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
clz32()
cos()
cosh()
E
exp()
expm1()
floor()
fround()
LN2
LN10
log()
log10()
log1p()
log2()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sign()
sin()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()

JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()

JS OperatorsJS RegExp
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()

(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx

JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while

JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()

Шаг 2: Получаем данные из localStorage

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

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

componentDidMount() {
const rememberMe = localStorage.getItem(‘rememberMe’) === ‘true’;
const user = rememberMe ? localStorage.getItem(‘user’) : »;
this.setState({ user, rememberMe });
}

1
2
3
4
5

componentDidMount(){

constrememberMe=localStorage.getItem(‘rememberMe’)===’true’;

constuser=rememberMe?localStorage.getItem(‘user’)»;

this.setState({user,rememberMe});

}

Теперь давайте углубимся в код:

Первым делом мы получаем значение “Remember me”

Уже обратили внимание, что сравнение идёт со строкой “true”? Это потому что  хранит данные как строки. Таким образом нам надо получить хранящееся значение и запарсить его обратно в логический тип данных, перед его непосредственным использованием

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

Далее мы получаем имя пользователя, но только в том случае, если  имеет значение .

И под конец мы назначаем эти значения стейту компонента.

И вот она магия!

И ещё совет

Как я говорил выше,  может хранить данные только в виде строк. Если вы имеете дело только с несколькими сохраненными значениями, то это не очень то и большая проблема. Но если вы хотите воспользоваться  на полную катушку в вашем приложении, то я очень советую взять на вооружение библиотеку, которая облегчит сохранение и получение данных, обойдя стороной такие процессы, как парсинг и обращение в строку. В этом деле идеально может подойти проверенная в боях Store.js. Это моя личная рекомендация.

Заключение

В React  очень просто использовать. Просто определите в каких случаях лучше сохранять и получать свои данные. Этот момент будет меняться от компонента к компоненту.

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

Если вам нужна хорошая библиотека для работы со значениями , то рассмотрите использование Store.js.

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

Хотя в истории было много уловок и обходных путей, нынешнее состояние 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? На данный момент практически ничего, кроме некоторых технологических демонстраций. Через год? Возможно.

Итого

IndexedDB можно рассматривать как «localStorage на стероидах». Это простая база данных типа ключ-значение, достаточно мощная для оффлайн приложений, но простая в использовании.

Лучшим руководством является спецификация, текущая версия 2.0, но также поддерживаются несколько методов из 3.0 (не так много отличий) версии.

Использование можно описать в нескольких фразах:

  1. Подключить обёртку над промисами, например idb.
  2. Открыть базу данных:
    • Создание хранилищ объектов и индексов происходит в обработчике .
    • Обновление версии – либо сравнивая номера версий, либо можно проверить что существует, а что нет.
  3. Для запросов:
    • Создать транзакцию (можно указать readwrite, если надо).
    • Получить хранилище объектов .
  4. Затем для поиска по ключу вызываем методы непосредственно у хранилища объектов.
  5. Если данные не помещаются в памяти, то используйте курсор.

Демо-приложение:

Результат
index.html

Добавить комментарий

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

Adblock
detector