Сохранить объекты 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/


Это работает для меня. Я получаю работающий объект 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

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



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)
})

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);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.