Хранение объектов в HTML5 localStorage

2119

Я хотел бы сохранить объект 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%, но ответы все еще могут представлять интерес.

  • 14
    Кстати, вы правильно прочитали «алгоритм структурированного клонирования», просто спецификация была изменена с значений только для строки на это после того, как реализации вышли. Я отправил сообщение об ошибке bugzilla.mozilla.org/show_bug.cgi?id=538142 в mozilla для отслеживания этой проблемы.
  • 2
    Это похоже на работу для indexedDB ...
Показать ещё 3 комментария
Теги:
local-storage

27 ответов

2851
Лучший ответ

Глядя на Apple, Mozilla и Microsoft, функциональность, судя по всему, ограничивается обработкой только пары строк/значений.

Обходным решением может быть укрепить ваш объект перед его сохранением, а затем проанализировать его при его получении:

var testObject = { 'one': 1, 'two': 2, 'three': 3 };

// Put the object into storage
localStorage.setItem('testObject', JSON.stringify(testObject));

// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');

console.log('retrievedObject: ', JSON.parse(retrievedObject));
  • 137
    обратите внимание, что любые метаданные будут удалены. вы просто получаете объект с парами ключ-значение, поэтому любой объект с поведением необходимо перестроить.
  • 4
    @CMS может setItem выдать какое-то исключение, если данные превышают емкость?
Показать ещё 3 комментария
572

Небольшое улучшение по варианту:

Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
    var value = this.getItem(key);
    return value && JSON.parse(value);
}

Из -за оценки короткого замыкания getObject() немедленно возвращает значение null если key не находится в хранилище. Он также не будет SyntaxError исключение SyntaxError если value равно "" (пустая строка; JSON.parse() не может справиться с этим).

  • 41
    Я просто хочу быстро добавить использование, поскольку это не было сразу понятно для меня: var userObject = { userId: 24, name: 'Jack Bauer' }; И установить его localStorage.setObject('user', userObject); Затем верните его из хранилища userObject = localStorage.getObject('user'); Вы даже можете хранить массив объектов, если хотите.
  • 0
    когда вы возвращаете this.getItem (ключ) && JSON.parse (this.getItem (ключ)), объединяет ли он эти две вещи? Я никогда не видел такой способ вернуть что-то.
Показать ещё 8 комментариев
190

Возможно, вам будет полезно расширить объект Storage с помощью этих удобных методов:

Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
    return JSON.parse(this.getItem(key));
}

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

  • 13
    Хорошая идея - включить подход CMS в функцию, для этого просто нужны функциональные тесты: один для JSON.stringify, один для JSON.parse и один для проверки, может ли localStorage действительно устанавливать и извлекать объект. Изменение хост-объектов не очень хорошая идея; Я бы предпочел видеть это как отдельный метод, а не как localStorage.setObject .
  • 4
    Этот getObject() SyntaxError исключение SyntaxError если сохраненное значение равно "" , потому что JSON.parse() не может это обработать. Смотрите подробности в моем редактировании ответа Гурии.
Показать ещё 1 комментарий
66

Расширение объекта Storage является прекрасным решением. Для моего API я создал фасад для localStorage, а затем проверяю, является ли это объектом или нет при настройке и получении.

var data = {
  set: function(key, value) {
    if (!key || !value) {return;}

    if (typeof value === "object") {
      value = JSON.stringify(value);
    }
    localStorage.setItem(key, value);
  },
  get: function(key) {
    var value = localStorage.getItem(key);

    if (!value) {return;}

    // assume it is an object that has been stringified
    if (value[0] === "{") {
      value = JSON.parse(value);
    }

    return value;
  }
}
  • 1
    Это было почти то, что мне было нужно. Просто нужно было добавить if (value == null) {return false} перед комментарием, иначе это привело к ошибке при проверке существования ключа в localStorage.
  • 2
    Это довольно круто на самом деле. Согласитесь с @FrancescoFrapporti, вам нужен if для нулевых значений. Я также добавил '|| value [0] == "[" 'test в случае, если там есть массив.
Показать ещё 7 комментариев
50

Существует большая библиотека, которая обертывает множество решений, поэтому даже поддерживает более старые браузеры, называемые jStorage

Вы можете установить объект

$.jStorage.set(key, value)

И легко получить его

value = $.jStorage.get(key)
value = $.jStorage.get(key, "default value")
  • 4
    $ нелегально !!!
  • 2
    @SuperUberDuper jStorage требуется Prototype, MooTools или jQuery
49

Stringify не решает всех проблем

Похоже, что ответы здесь не охватывают все типы, которые возможны в JavaScript, поэтому вот несколько кратких примеров того, как правильно их решить:

//Objects and Arrays:
    var obj = {key: "value"};
    localStorage.object = JSON.stringify(obj);  //Will ignore private members
    obj = JSON.parse(localStorage.object);
//Boolean:
    var bool = false;
    localStorage.bool = bool;
    bool = (localStorage.bool === "true");
//Numbers:
    var num = 42;
    localStorage.num = num;
    num = +localStorage.num;    //short for "num = parseFloat(localStorage.num);"
//Dates:
    var date = Date.now();
    localStorage.date = date;
    date = new Date(parseInt(localStorage.date));
//Regular expressions:
    var regex = /^No\.[\d]*$/i;     //usage example: "No.42".match(regex);
    localStorage.regex = regex;
    var components = localStorage.regex.match("^/(.*)/([a-z]*)$");
    regex = new RegExp(components[1], components[2]);
//Functions (not recommended):
    function func(){}
    localStorage.func = func;
    eval( localStorage.func );      //recreates the function with the name "func"

Я не рекомендую хранить функции, потому что eval() злой может привести к проблемам безопасности, оптимизации и отладки.       В общем случае eval() никогда не следует использовать в JavaScript-коде.

Частные члены

Проблема с использованием JSON.stringify() для хранения объектов заключается в том, что эта функция не может сериализовать закрытых членов. Эту проблему можно решить, перезаписав метод .toString() (который неявно используется при хранении данных в веб-хранилище):

//Object with private and public members:
    function MyClass(privateContent, publicContent){
        var privateMember = privateContent || "defaultPrivateValue";
        this.publicMember = publicContent  || "defaultPublicValue";

        this.toString = function(){
            return '{"private": "' + privateMember + '", "public": "' + this.publicMember + '"}';
        };
    }
    MyClass.fromString = function(serialisedString){
        var properties = JSON.parse(serialisedString || "{}");
        return new MyClass( properties.private, properties.public );
    };
//Storing:
    var obj = new MyClass("invisible", "visible");
    localStorage.object = obj;
//Loading:
    obj = MyClass.fromString(localStorage.object);

Циркулярные ссылки

Другая проблема stringify не может иметь дело с круговыми ссылками:

var obj = {};
obj["circular"] = obj;
localStorage.object = JSON.stringify(obj);  //Fails

В этом примере JSON.stringify() будет вызывать TypeError "Преобразование круговой структуры в JSON".       Если необходимо сохранить циклические ссылки, может использоваться второй параметр JSON.stringify():

var obj = {id: 1, sub: {}};
obj.sub["circular"] = obj;
localStorage.object = JSON.stringify( obj, function( key, value) {
    if( key == 'circular') {
        return "$ref"+value.id+"$";
    } else {
        return value;
    }
});

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

Есть вопрос о том, как SO справляется с этой проблемой: Stringify (конвертировать в JSON) объект JavaScript с круговой ссылкой

30

Использование объектов JSON для локального хранилища:

//SET

var m={name:'Hero',Title:'developer'};
localStorage.setItem('us', JSON.stringify(m));

//GET

var gm =JSON.parse(localStorage.getItem('us'));
console.log(gm.name);

//Итерирование всех локальных ключей хранения и значений

for (var i = 0, len = localStorage.length; i < len; ++i) {
  console.log(localStorage.getItem(localStorage.key(i)));
}

//УДАЛИТЬ

localStorage.removeItem('us');
delete window.localStorage["us"];
27

В теории можно хранить объекты с функциями:

function store (a)
{
  var c = {f: {}, d: {}};
  for (var k in a)
  {
    if (a.hasOwnProperty(k) && typeof a[k] === 'function')
    {
      c.f[k] = encodeURIComponent(a[k]);
    }
  }

  c.d = a;
  var data = JSON.stringify(c);
  window.localStorage.setItem('CODE', data);
}

function restore ()
{
  var data = window.localStorage.getItem('CODE');
  data = JSON.parse(data);
  var b = data.d;

  for (var k in data.f)
  {
    if (data.f.hasOwnProperty(k))
    {
      b[k] = eval("(" + decodeURIComponent(data.f[k]) + ")");
    }
  }

  return b;
}

Однако сериализация/десериализация функций ненадежна, поскольку зависит от реализации.

  • 1
    Сериализация / десериализация функций ненадежна, поскольку зависит от реализации . Также вы хотите заменить cf[k] = escape(a[k]); с Unicode-безопасным cf[k] = encodeURIComponent(a[k]); и eval('b.' + k + ' = ' + unescape(data.f[k])); с b[k] = eval("(" + decodeURIComponent(data.f[k]) + ")"); , Скобки требуются, потому что ваша функция, если она сериализована должным образом, скорее всего, будет анонимной, что не является допустимым / Statement / (поэтому eval() ) может SyntaxError исключение SyntaxError противном случае).
  • 0
    И typeof - это оператор , не пишите его так, как если бы это была функция. Замените typeof(a[k]) на typeof a[k] .
Показать ещё 3 комментария
23

Вы также можете переопределить методы хранения по умолчанию setItem(key,value) и getItem(key) для обработки объектов/массивов, как и любой другой тип данных. Таким образом, вы можете просто вызвать localStorage.setItem(key,value) и localStorage.getItem(key), как обычно.

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

Storage.prototype._setItem = Storage.prototype.setItem;
Storage.prototype.setItem = function(key, value)
{
  this._setItem(key, JSON.stringify(value));
}

Storage.prototype._getItem = Storage.prototype.getItem;
Storage.prototype.getItem = function(key)
{  
  try
  {
    return JSON.parse(this._getItem(key));
  }
  catch(e)
  {
    return this._getItem(key);
  }
}
  • 12
    Считается плохой практикой менять собственные / встроенные объектные API. Смотрите другие ответы для других решений.
  • 0
    Хорошо, если вы никогда не захотите использовать какие-либо библиотеки, которые зависят от спецификации.
21

Я пришел на это сообщение после того, как нажал на другое сообщение, которое было закрыто как дубликат этого - под названием "Как сохранить массив в localstorage?". Это хорошо, за исключением того, что ни один поток не дает полного ответа о том, как вы можете поддерживать массив в localStorage, однако мне удалось создать решение на основе информации, содержащейся в обоих потоках.

Итак, если кто-то хочет иметь возможность нажимать/поп/перемещать элементы внутри массива, и они хотят, чтобы этот массив хранился в localStorage или даже в sessionStorage, вы здесь:

Storage.prototype.getArray = function(arrayName) {
  var thisArray = [];
  var fetchArrayObject = this.getItem(arrayName);
  if (typeof fetchArrayObject !== 'undefined') {
    if (fetchArrayObject !== null) { thisArray = JSON.parse(fetchArrayObject); }
  }
  return thisArray;
}

Storage.prototype.pushArrayItem = function(arrayName,arrayItem) {
  var existingArray = this.getArray(arrayName);
  existingArray.push(arrayItem);
  this.setItem(arrayName,JSON.stringify(existingArray));
}

Storage.prototype.popArrayItem = function(arrayName) {
  var arrayItem = {};
  var existingArray = this.getArray(arrayName);
  if (existingArray.length > 0) {
    arrayItem = existingArray.pop();
    this.setItem(arrayName,JSON.stringify(existingArray));
  }
  return arrayItem;
}

Storage.prototype.shiftArrayItem = function(arrayName) {
  var arrayItem = {};
  var existingArray = this.getArray(arrayName);
  if (existingArray.length > 0) {
    arrayItem = existingArray.shift();
    this.setItem(arrayName,JSON.stringify(existingArray));
  }
  return arrayItem;
}

Storage.prototype.unshiftArrayItem = function(arrayName,arrayItem) {
  var existingArray = this.getArray(arrayName);
  existingArray.unshift(arrayItem);
  this.setItem(arrayName,JSON.stringify(existingArray));
}

Storage.prototype.deleteArray = function(arrayName) {
  this.removeItem(arrayName);
}

пример использования - сохранение простых строк в массиве localStorage:

localStorage.pushArrayItem('myArray','item one');
localStorage.pushArrayItem('myArray','item two');

пример использования - сохранение объектов в массиве sessionStorage:

var item1 = {}; item1.name = 'fred'; item1.age = 48;
sessionStorage.pushArrayItem('myArray',item1);

var item2 = {}; item2.name = 'dave'; item2.age = 22;
sessionStorage.pushArrayItem('myArray',item2);

общие методы управления массивами:

.pushArrayItem(arrayName,arrayItem); -> adds an element onto end of named array
.unshiftArrayItem(arrayName,arrayItem); -> adds an element onto front of named array
.popArrayItem(arrayName); -> removes & returns last array element
.shiftArrayItem(arrayName); -> removes & returns first array element
.getArray(arrayName); -> returns entire array
.deleteArray(arrayName); -> removes entire array from storage
  • 0
    Это очень удобный набор методов для манипулирования массивами, хранящимися в localStorage или sessionStorage, и заслуживает гораздо большего уважения, чем привлекло. @ Энди Лоренц Спасибо, что нашли время, чтобы поделиться!
13

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

8

Я немного изменил один из ответов, опрошенных сверху. Я поклонник иметь одну функцию вместо 2, если это не нужно.

Storage.prototype.object = function(key, val) {
    if ( typeof val === "undefined" ) {
        var value = this.getItem(key);
        return value ? JSON.parse(value) : null;
    } else {
        this.setItem(key, JSON.stringify(val));
    }
}

localStorage.object("test", {a : 1}); //set value
localStorage.object("test"); //get value

Кроме того, если значение не задано, оно возвращает null вместо false. false имеет некоторый смысл, null не имеет.

  • 1
    В отличие от localStorage API, моя библиотека возвращает undefined при попытке получить несуществующее значение ключа. Я согласен, что ложь имеет значение, но и ноль . Переменная присваивается нулевое значение отсутствует какое - либо значение (но он установлен), тогда как не определено не является инициализирован.
5

Вы можете использовать localDataStorage для прозрачного хранения типов данных javascript (Array, Boolean, Date, Float, Integer, String и Object). Он также обеспечивает легкую обфускацию данных, автоматически сжимает строки, облегчает запрос по ключу (имя), а также запрос по (ключевому) значению и помогает обеспечить сегментированное разделяемое хранилище в том же домене с помощью префикса ключей.

[ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ] Я являюсь автором утилиты [/DISCLAIMER]

Примеры:

localDataStorage.set( 'key1', 'Belgian' )
localDataStorage.set( 'key2', 1200.0047 )
localDataStorage.set( 'key3', true )
localDataStorage.set( 'key4', { 'RSK' : [1,'3',5,'7',9] } )
localDataStorage.set( 'key5', null )

localDataStorage.get( 'key1' )   -->   'Belgian'
localDataStorage.get( 'key2' )   -->   1200.0047
localDataStorage.get( 'key3' )   -->   true
localDataStorage.get( 'key4' )   -->   Object {RSK: Array(5)}
localDataStorage.get( 'key5' )   -->   null

Как вы можете видеть, примитивные значения соблюдаются.

  • 0
    Это блестящий ресурс и именно то, что мне нужно. Я делаю Ionic-приложения с AngularJS, где мне нужно сохранить определенные объекты javascript в localStorage, и до этого момента я только что делал JSON.parse и JSON.stringify, и они работают, но это немного сложнее, чем возможность просто использовать утилиту, как эта. Я собираюсь попробовать это.
4

Вы можете использовать ejson для хранения объектов в виде строк.

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

  • Дата (JavaScript Date)
  • Двоичный (JavaScript Uint8Array или результат EJSON.newBinary)
  • Пользовательские типы (см. EJSON.addType. Например, Mongo.ObjectID реализуется таким образом.)

Все сериализации EJSON также действительны JSON. Например, объект с датой и двоичным буфером будет сериализован в EJSON как:

{
  "d": {"$date": 1358205756553},
  "b": {"$binary": "c3VyZS4="}
}

Вот моя обложка localStorage, использующая ejson

https://github.com/UziTech/storage.js

Я добавил некоторые типы в свою обертку, включая регулярные выражения и функции

4

Другой вариант - использовать существующий плагин.

Например persisto - проект с открытым исходным кодом, который обеспечивает легкий интерфейс для локального хранилища /sessionStorage и автоматизирует сохранение для полей формы (ввод, переключатели и флажки).

Изображение 2058

(Отказ от ответственности: я автор).

  • 0
    Я все еще работаю с моим файлом readme, но моя версия не требует jQuery, как это, кажется, и есть, но она предоставляет альтернативу для работы с объектами jQuery. Я добавлю больше в ближайшем будущем, так как я буду больше с ним работать, чтобы помочь ему в дальнейшей обработке различных объектов jQuery и поддерживать такие вещи, как постоянные данные. Также +1 за попытку предоставить более простое решение! Кроме того, он использует все традиционные методы localStroage ; exp: var lsh = new localStorageHelper(); lsh.setItem('bob', 'bill'); Также включает в себя события.
4

Улучшение ответа @Guria:

Storage.prototype.setObject = function (key, value) {
    this.setItem(key, JSON.stringify(value));
};


Storage.prototype.getObject = function (key) {
    var value = this.getItem(key);
    try {
        return JSON.parse(value);
    }
    catch(err) {
        console.log("JSON parse failed for lookup of ", key, "\n error was: ", err);
        return null;
    }
};
3

Я сделал еще одну минималистическую оболочку с только 20 строками кода, чтобы разрешить ее использовать, как и должно:

localStorage.set('myKey',{a:[1,2,5], b: 'ok'});
localStorage.has('myKey');   // --> true
localStorage.get('myKey');   // --> {a:[1,2,5], b: 'ok'}
localStorage.keys();         // --> ['myKey']
localStorage.remove('myKey');

https://github.com/zevero/simpleWebstorage

3

http://rhaboo.org - это уровень сахара в местном хранилище, который позволяет писать такие вещи:

var store = Rhaboo.persistent('Some name');
store.write('count', store.count ? store.count+1 : 1);
store.write('somethingfancy', {
  one: ['man', 'went'],
  2: 'mow',
  went: [  2, { mow: ['a', 'meadow' ] }, {}  ]
});
store.somethingfancy.went[1].mow.write(1, 'lawn');

Он не использует JSON.stringify/parse, потому что это было бы неточно и медленно на больших объектах. Вместо этого каждое значение терминала имеет свою собственную запись localStorage.

Вероятно, вы можете догадаться, что я мог бы иметь какое-то отношение к rhaboo; -)

Адриан.

2

Для пользователей Postscript, желающих установить и получить типизированные свойства:

/**
 * Silly wrapper to be able to type the storage keys
 */
export class TypedStorage<T> {

    public removeItem(key: keyof T): void {
        localStorage.removeItem(key);
    }

    public getItem<K extends keyof T>(key: K): T[K] | null {
        const data: string | null =  localStorage.getItem(key);
        return JSON.parse(data);
    }

    public setItem<K extends keyof T>(key: K, value: T[K]): void {
        const data: string = JSON.stringify(value);
        localStorage.setItem(key, data);
    }
}

{ public removeItem(key: keyof T): void { localStorage.removeItem(key); } public getItem(key: K): T[K] | null { const data: string | null = localStorage.getItem(key); return JSON.parse(data); } public setItem(key: K, value: T[K]): void { const data: string = JSON.stringify(value); localStorage.setItem(key, data); } } //write an interface for the storage interface MyStore { age: number, name: string, address: {city:string} } const storage: TypedStorage= new TypedStorage(); storage.setItem("wrong key", "");//error unknown key storage.setItem("age", "hello");//error, age should be number storage.setItem("address", {city:"Here"});//ok const address: {city:string} = storage.getItem("address"); rel="nofollow noreferrer">Пример использования:

// write an interface for the storage
interface MyStore {
   age: number,
   name: string,
   address: {city:string}
}

const storage: TypedStorage<MyStore> = new TypedStorage<MyStore>();

storage.setItem("wrong key", ""); // error unknown key
storage.setItem("age", "hello"); // error, age should be number
storage.setItem("address", {city:"Here"}); // ok

const address: {city:string} = storage.getItem("address");
1

Лучше вы выполняете функции setter и getter в localStorage, таким образом, у вас будет лучший контроль и вам не придется повторять синтаксический анализ JSON и все. он будет обрабатывать ваш ("") пустой строковый ключ/файл данных плавно.

function setItemInStorage(dataKey, data){
    localStorage.setItem(dataKey, JSON.stringify(data));
}

function getItemFromStorage(dataKey){
    var data = localStorage.getItem(dataKey);
    return data? JSON.parse(data): null ;
}

setItemInStorage('user', { name:'tony stark' });
getItemFromStorage('user'); /* return {name:'tony stark'} */
1

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

var obj = {a: "lol", b: "A", c: "hello world"};
function saveObj (key){
    var j = "";
    for(var i in obj){
        j += (i+"|"+obj[i]+"~");
    }
    localStorage.setItem(key, j);
} // Saving Method
function getObj (key){
    var j = {};
    var k = localStorage.getItem(key).split("~");
    for(var l in k){
        var m = k[l].split("|");
        j[m[0]] = m[1];
    }
    return j;
}
saveObj("obj"); // undefined
getObj("obj"); // {a: "lol", b: "A", c: "hello world"}

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

1

Посмотрите это

Скажем, у вас есть следующий массив, называемый фильмами:

var movies = ["Reservoir Dogs", "Pulp Fiction", "Jackie Brown", 
              "Kill Bill", "Death Proof", "Inglourious Basterds"];

Используя функцию stringify, ваш массив фильмов можно преобразовать в строку, используя следующий синтаксис:

localStorage.setItem("quentinTarantino", JSON.stringify(movies));

Обратите внимание, что мои данные хранятся под ключом quentinTarantino.

Извлечение данных

var retrievedData = localStorage.getItem("quentinTarantino");

Чтобы преобразовать из строки обратно в объект, используйте функцию разбора JSON:

var movies2 = JSON.parse(retrievedData);

Вы можете вызвать все методы массива в ваших фильмах2

  • 1
    Обратите внимание, что ответы только на ссылки не приветствуются, поэтому ответы SO должны быть конечной точкой поиска решения (в отличие от еще одной остановки ссылок, которая, как правило, со временем устареет). Пожалуйста, рассмотрите возможность добавления отдельного краткого обзора здесь, сохраняя ссылку в качестве ссылки.
  • 5
    Также обратите внимание, что ваш ответ не содержит ничего, кроме существующего пятилетнего ответа, который имеет более 1500 голосов. Я ценю то, что вы пытаетесь ответить на мой вопрос, но, пожалуйста, проверьте, дает ли ваш ответ какую-либо ценность, отличную от других более старых ответов.
1

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

То, что я сделал.

Если вы хотите, чтобы свойство 1 localStorage было волшебным:

var prop = ObjectStorage(localStorage, 'prop');

Если вам нужно несколько:

var storage = ObjectStorage(localStorage, ['prop', 'more', 'props']);

Все, что вы делаете с prop, или объекты внутри storage будет автоматически сохранено в localStorage. Вы всегда играете с реальным объектом, поэтому можете делать такие вещи:

storage.data.list.push('more data');
storage.another.list.splice(1, 2, {another: 'object'});

И каждый новый объект внутри отслеживаемый объект будет автоматически отслеживаться.

Очень большой недостаток: зависит от Object.observe(), поэтому он имеет очень ограниченную поддержку браузера. И не похоже, что в ближайшее время они появятся в Firefox или Edge.

1

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

Ex-, в котором вы можете решить это, используя этот фрагмент

// for set object in db
db.local.setJSON("key", {name: "xyz"});  

// for get object form db
db.local.getJSON("key");

https://github.com/pankajbisht/openDB

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

1

Здесь определенная версия кода, отправленного @danott

Он также реализует значение удалить из localstorage и показывает, как добавить слой Getter и Setter, чтобы вместо

localstorage.setItem(preview, true)

вы можете написать

config.preview = true

Хорошо здесь были go:

var PT=Storage.prototype

if (typeof PT._setItem >='u') PT._setItem = PT.setItem;
PT.setItem = function(key, value)
{
  if (typeof value >='u')//..ndefined
    this.removeItem(key)
  else
    this._setItem(key, JSON.stringify(value));
}

if (typeof PT._getItem >='u') PT._getItem = PT.getItem;
PT.getItem = function(key)
{  
  var ItemData = this._getItem(key)
  try
  {
    return JSON.parse(ItemData);
  }
  catch(e)
  {
    return ItemData;
  }
}

// Aliases for localStorage.set/getItem 
get =   localStorage.getItem.bind(localStorage)
set =   localStorage.setItem.bind(localStorage)

// Create ConfigWrapperObject
var config = {}

// Helper to create getter & setter
function configCreate(PropToAdd){
    Object.defineProperty( config, PropToAdd, {
      get: function ()      { return (  get(PropToAdd)      ) },
      set: function (val)   {           set(PropToAdd,  val ) }
    })
}
//------------------------------

// Usage Part
// Create properties
configCreate('preview')
configCreate('notification')
//...

// Config Data transfer
//set
config.preview = true

//get
config.preview

// delete
config.preview = undefined

Хорошо, вы можете удалить часть псевдонимов с помощью .bind(...). Однако я просто положил его, так как это действительно хорошо знать об этом. Я взял несколько часов, чтобы узнать, почему простой get = localStorage.getItem; не работает

1

Небольшой пример библиотеки, которая использует localStorage для отслеживания полученных сообщений от контактов:

// This class is supposed to be used to keep a track of received message per contacts.
// You have only four methods:

// 1 - Tells you if you can use this library or not...
function isLocalStorageSupported(){
    if(typeof(Storage) !== "undefined" && window['localStorage'] != null ) {
         return true;
     } else {
         return false;
     }
 }

// 2 - Give the list of contacts, a contact is created when you store the first message
 function getContacts(){
    var result = new Array();
    for ( var i = 0, len = localStorage.length; i < len; ++i ) {
        result.push(localStorage.key(i));
    }
    return result;
 }

 // 3 - store a message for a contact
 function storeMessage(contact, message){
    var allMessages;
    var currentMessages = localStorage.getItem(contact);
    if(currentMessages == null){
        var newList = new Array();
        newList.push(message);
        currentMessages = JSON.stringify(newList);
    }
    else
    {
        var currentList =JSON.parse(currentMessages);
        currentList.push(message);
        currentMessages = JSON.stringify(currentList);
    }
    localStorage.setItem(contact, currentMessages);
 }

 // 4 - read the messages of a contact
 function readMessages(contact){

    var result = new Array();
    var currentMessages = localStorage.getItem(contact);

    if(currentMessages != null){
        result =JSON.parse(currentMessages);
    }
    return result;
 }
-6

Прокрутка по локальной сети

var retrievedData = localStorage.getItem("MyCart");                 

retrievedData.forEach(function (item) {
   console.log(item.itemid);
});
  • 3
    Локальное хранилище не работает таким образом. Вы ограничены строками ... требуется сериализация.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню