Хранение объектов в HTML5 localStorage
Я'хочу сохранить объект JavaScript в HTML5 localStorage
, но мой объект, очевидно, преобразуется в строку.
Я могу хранить и извлекать примитивные типы JavaScript и массивы с помощью localStorage
, но объекты, похоже, не работают. Должны ли они работать?
Вот мой код:
var testObject = { 'one': 1, 'two': 2, 'three': 3 };
console.log('typeof testObject: ' + typeof testObject);
console.log('testObject properties:');
for (var prop in testObject) {
console.log(' ' + prop + ': ' + testObject[prop]);
}
// Put the object into storage
localStorage.setItem('testObject', testObject);
// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');
console.log('typeof retrievedObject: ' + typeof retrievedObject);
console.log('Value of retrievedObject: ' + retrievedObject);
Консольный вывод
typeof testObject: object
testObject properties:
one: 1
two: 2
three: 3
typeof retrievedObject: string
Value of retrievedObject: [object Object]
Мне кажется, что метод setItem
преобразует входные данные в строку перед их сохранением.
Я наблюдаю такое поведение в Safari, Chrome и Firefox, поэтому я предполагаю, что это мое непонимание спецификации HTML5 Web Storage, а не ошибка или ограничение конкретного браузера.
Я попытался понять алгоритм структурированного клона, описанный в http://www.w3.org/TR/html5/infrastructure.html. Я не совсем понимаю, о чем там говорится, но, возможно, моя проблема связана с тем, что свойства моего объекта не являются перечислимыми (???).
Есть ли простой обходной путь?
Обновление: W3C в конечном итоге изменил свое мнение о спецификации структурированного клона и решил изменить спецификацию, чтобы она соответствовала реализации. См. https://www.w3.org/Bugs/Public/show_bug.cgi?id=12111. Таким образом, этот вопрос больше не является на 100% актуальным, но ответы на него все еще могут представлять интерес.
Изучая документацию Apple, Mozilla и Mozilla again, кажется, что функциональность ограничена обработкой только строковых пар ключ/значение.
Обходным решением может быть стрингизация вашего объекта перед его сохранением, а затем разбор его при получении:
Небольшое улучшение варианта:
Из-за оценки замыкания,
getObject()
будет немедленно возвращатьnull
, еслиkey
не находится в хранилище. Она также не выбросит исключениеSyntaxError
, еслиvalue
будет""
(пустая строка;JSON.parse()
не может обработать это).Возможно, вам будет полезно расширить объект Storage этими удобными методами:
Таким образом, вы получите функциональность, которая вам действительно нужна, даже если API поддерживает только строки.
Расширение объекта хранения является удивительным решением. Для моих API, я создал фасад для localStorage, а затем проверить, если это объект или нет во время установки и получения.
Преобразовать в строки Не'т решить все проблемы
Кажется, что ответы здесь Дон'т охватывают все типы, которые возможны в JavaScript, так вот несколько коротких примеров о том, как правильно бороться с ними:
Не рекомендую для хранения функции, потому что функция eval()
это зло может привести к вопросам, касающимся безопасности, оптимизации и отладки. В целом, функции eval()
не должны использоваться в коде JavaScript.Частные члены
Проблема с использованием формата JSON.преобразовать в строки () для того, чтобы хранить объекты, то эта функция не может serialise частных членов. Эта проблема может быть решена путем перезаписи
.метод toString()
метод (который вызывается неявно при хранении данных в веб-хранилище):Циклические ссылки
Преобразовать в строки еще одной проблемой может'т бороться с циклическими ссылками:
В этом примере,
формат JSON.преобразовать в строки()
броситошибку TypeError
"и преобразование круговой структуры в JSON и". Если хранение циклические ссылки должны быть поддержаны, второго параметра `формат JSON.преобразовать в строки () могут быть использованы:Однако найти эффективное решение для хранения циклических ссылок сильно зависит от задач, которые необходимо решить, и восстановление таких данных не является тривиальной, либо.
Есть уже какой-то вопрос так борюсь с этой проблемой: https://stackoverflow.com/questions/10392293/stringify-javascript-object-with-circular-reference/12659424#12659424
Есть большая библиотека, которая обертывает много решений, поэтому она даже поддерживает старые браузеры называют jStorage
Вы можете установить объект
И легко извлечь его
В теории, можно хранить объекты с функциями:
Однако, функции сериализации/десериализации ненадежны, потому что это является зависящим от реализации.
Я приехал в этот пост после удара на другой пост, который был закрыт, так как является дубликатом этот - под названием 'Как сохранить массив в localStorage?'. Это нормально, только ни один поток на самом деле обеспечивает полный ответ на вопрос, как можно сохранить массив в localStorage - однако мне удалось выработать решение на основе информации, содержащейся в обе нити.
Так что если кто еще хочет быть в состоянии пуш/поп/элементы сдвига в массиве, и они хотят, что массив хранится в localStorage или sessionStorage действительно, здесь вы идете:
пример использования - хранения простые строки в массив объект localStorage:
пример использования - хранение объектов в массиве sessionStorage:
общие методы для работы с массивами:
Рекомендую использовать библиотеку абстракции для многих из описанных здесь, а также обеспечения лучшей совместимости. Много вариантов:
Вы можете использовать localDataStorage прозрачно магазине в JavaScript типы данных (массив, булево, дата, с плавающей точкой, целое число, строка и объект). Она также обеспечивает легкий обфускация данных, автоматически сжимает струны, облегчает запрос по ключу (имени), а также запрос (ключ) значение, и помогает обеспечить сегментированные общего хранилища в пределах одного домена, предварив ключи.
[Отказ] Я автор утилиты [/отказ]
Примеры:
Как видите, примитивные ценности уважаются.
Вы можете использовать ejson для хранения объектов в виде строк.
Вот мой фантик localStorage с использованием ejson
https://github.com/UziTech/storage.js
Я добавил некоторые типы в мою оболочку, включая регулярные выражения и функции
Другим вариантом было бы использовать существующий плагин.
Например persisto - проект с открытым исходным кодом, которая предоставляет простой интерфейс в localStorage/sessionStorage и автоматизирует сохранение полей формы (ввода, радио-кнопки и чекбоксы).
(Отказ от ответственности: я автор.)
Я сделал еще одну минималистичную оболочку с всего лишь 20 строк кода, чтобы использовать его как следует:
https://github.com/zevero/simpleWebstorage
http://rhaboo.org это сахарный слой хранилище localStorage, которое позволяет писать такие вещи:
Это не'т использовать JSON.преобразовать в строки/разбор, потому что это будет неточное и медленное на больших объектах. Вместо этого, каждый стоимостью терминал имеет свои собственные записи хранилище localStorage.
Вы, наверное, можете догадаться, что я может что-то делать с rhaboo ;-)
Эдриан.
Для машинопись пользователей, готовых установить и получить типизированные свойства:
Пример использования:
Чтобы сохранить объект, вы могли бы сделать буквы, которые вы можете использовать, чтобы получить объект из строки в объект (не имеет смысла). Например
Эта техника будет вызвать некоторые затруднения, если вы используете буквы, которые вы использовали, чтобы разделить объект, и это's также очень опытно.
Я сделал то, что не'т сломать существующие объекты хранения, но и создает оболочку, так что вы можете делать то, что вы хотите. Результат нормальный объект, ни методы, с доступом как с любым объектом.
Что я сделал.
Если вы хотите 1
хранилище localStorage
свойство магии:Если вам нужно несколько:
Все, что вы делаете, чтобы "опора", или объектов внутри "склад" будет автоматически сохранен в хранилище localStorage`. Вы'вновь всегда играет с реального объекта, так что вы можете делать вещи, как это:
И каждый новый объект внутри отслеживаемый объект будет автоматически отслеживаться.
Очень большой недостаток: это зависит от объекта.наблюдать ()`, поэтому она имеет очень ограниченный браузер поддержка. И это вовсе'т выглядеть так, как она'll быть пришествие для Firefox или края в ближайшее время.
Вот некоторые Расширенная версия код написал @danott
в Это'll тоже реализовать удалить значение из localStorage и показывает, как добавляет геттер и сеттер слой, поэтому вместо того, чтобы
хранилище localStorage.setitem класса(просмотр, правда)
вы можете написать
конфигурации.предварительный просмотр = истина
Ладно поехали:
Также вы можете лишить псевдонимы часть на <код>.привязать(...)</код>. Однако я просто положить его в, так как это's действительно хорошо, чтобы знать об этом. Я приняли меня часов, чтобы выяснить, почему простой <код>получайте = хранилище localStorage.метод getitem;</код> Дон't работа