Сохранить объекты Javascript в sessionStorage

152

SessionStorage и LocalStorage позволяют сохранять пары ключ / значение в веб-браузере. Значение должно быть строкой, а сохранение объектов js не является тривиальным.

var user = {'name':'John'};
sessionStorage.setItem('user', user);
var obj = sessionStorage.user; // obj='[object Object]' Not an object

В настоящее время вы можете обойти это ограничение, сериализовав объекты в JSON, а затем десериализовав их для восстановления объектов. Но Storage API всегда проходят через setItemи getItemметоды.

sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.getItem('user')); // An object :D

Могу ли я избежать этого ограничения?

Я просто хочу выполнить что-то вроде этого:

sessionStorage.user.name; // 'John'
sessionStorage.user.name = 'Mary';
sessionStorage.user.name // 'Mary'

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

Ферран Басора
источник
1
Я думал об этом сам. Я полагаю, что многие люди имеют. Но я не думаю, что методы получения и установки слишком обременительны. КСТАТИ; Вы можете сериализовать и проанализировать JavaScript, и MS наконец поддерживает те же стандартные объекты, что и все остальные. Дни потребности в таких пакетах, как JSON и jQuery, быстро подходят к концу.
Роджер Ф. Гэй
1
Я думаю, я не вижу ограничений. Может показаться излишним использовать JSON.stringify и JSON.parse, если у вас есть только тривиальные объекты, но если у вас есть даже объекты данных хорошего размера, эти два метода делают большую работу за вас.
Робусто
5
"Могу ли я избежать этого ограничения?" кажется вопросом
sonicblis
1
Ну или нет, этот вопрос помог мне решить проблему, так что спасибо.
Мэтт Уэст,

Ответы:

19

Либо вы можете использовать средства доступа, предоставляемые API-интерфейсом веб-хранилища, либо написать оболочку / адаптер. Из вашей заявленной проблемы с defineGetter / defineSetter звучит так, будто написание оболочки / адаптера - слишком много работы для вас.

Я, честно говоря, не знаю, что тебе сказать. Может быть, вы могли бы переоценить свое мнение о том, что является «смешным ограничением». API веб-хранилища - это то, чем он должен быть, хранилище ключей / значений.

Райан Олдс
источник
8
Извините, если я использовал неуместное слово с «нелепым». Замените его на «может быть так интересно». Я думаю, что webStorage - одно из самых захватывающих улучшений новой сети. Но сохранить только строки в значении карты ключей я считаю ограничением. Это похоже на продолжение печенья. Я знаю, что Storage - это спецификация не только для языка Javascript, но сериализация объектов может быть интересным улучшением. Что вы думаете?
Ферран Басора
2
Если JSON недостаточно, вы всегда можете написать свои собственные методы сериализации объектов.
Райан Олдс
110

Не могли бы вы «зачеркнуть» ваш объект ... затем использовать sessionStorage.setItem()для хранения этого строкового представления вашего объекта ... затем, когда вам это нужно, sessionStorage.getItem()и затем использовать$.parseJSON() для его возврата?

Рабочий пример http://jsfiddle.net/pKXMa/

afreeland
источник
Это работает для меня. Я получаю работающий объект Json после вызова $ .parseJSON ()
Олафур Трюггвасон
Некоторые системы, такие как аутентификация Web Api, возвращают объекты в форме Object {propertyOneWithoutQuotes: "<value1>", ... propertyNWithoutQuotes: "<valueN>"}, которые должны пройти через "stringify". Если имеется несколько источников, может быть лучше использовать stringify для стандартизации данных.
Jelgab
Это очень хороший ответ. Хорошо использовать JSON.stringify () для сериализации объекта и сохранения в sessionStorage. Затем он использует $ .parseJSON () для десериализации строки, чтобы получить объект.
Thomas.Benz
102

Решение состоит в том, чтобы привести в соответствие объект перед вызовом setItem в sessionStorage.

var user = {'name':'John'};
sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.user);
Рон
источник
Спасибо, что не
связали
12

Это динамическое решение, которое работает со всеми типами значений, включая объекты:

class Session extends Map {
  set(id, value) {
    if (typeof value === 'object') value = JSON.stringify(value);
    sessionStorage.setItem(id, value);
  }

  get(id) {
    const value = sessionStorage.getItem(id);
    try {
      return JSON.parse(value);
    } catch (e) {
      return value;
    }
  }
}

Затем :

const session = new Session();

session.set('name', {first: 'Ahmed', last : 'Toumi'});
session.get('name');
Абденнур ТУМИ
источник
5

Случай использования:

 sesssionStorage.setObj(1,{date:Date.now(),action:'save firstObject'});
 sesssionStorage.setObj(2,{date:Date.now(),action:'save 2nd object'}); 
 //Query first object
  sesssionStorage.getObj(1)
  //Retrieve date created of 2nd object
  new Date(sesssionStorage.getObj(1).date)

API

Storage.prototype.setObj = function(key, obj) {

        return this.setItem(key, JSON.stringify(obj))
    };
    
    Storage.prototype.getObj = function(key) {
        return JSON.parse(this.getItem(key))
    };
Абденнур ТУМИ
источник
4
Я думал, что одна из лучших практик в javascript - не создавать прототипы объектов, которыми вы не владеете. Использование Storage.prototype.setObj кажется плохой идеей.
britztopher
3
просто добавив обязательное .. убедитесь, что вы не добавляете этот прототип кода - и полагайтесь на него исключительно - без предварительной проверки, поддерживает ли его браузер. Хранение:if (typeof (Storage) !== "undefined"){ /* browser supports it */ }
JoeBrockhaus
4

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

Игорь Урисман
источник
3
    var user = {'name':'John'};
    sessionStorage['user'] = JSON.stringify(user);
    console.log(sessionStorage['user']);
Джиджо Паулозе
источник
2

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

пример :

// Store current user
store.set('user', { name:'Marcus' })

// Get current user
store.get('user')

// Remove current user
store.remove('user')

// Clear all keys
store.clearAll()

// Loop over all stored values
store.each(function(value, key) {
    console.log(key, '==', value)
})
3Dos
источник
0

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

function saveSession(obj) {
  sessionStorage.setItem("myObj", JSON.stringify(obj));
  return true;
}

function getSession() {
  var obj = {};
  if (typeof sessionStorage.myObj !== "undefined") {
    obj = JSON.parse(sessionStorage.myObj);
  }
  return obj;
}

Используйте это так: - Получить объект, изменить некоторые данные и сохранить обратно.

var obj = getSession();

obj.newProperty = "Prod"

saveSession(obj);
JerryGoyal
источник