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