Збережіть об'єкти 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, а потім десеріалізуючи їх для відновлення об'єктів. Але 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
Я сам про це думав. Я гадаю, багато людей. Але я не вважаю, що геттер і сеттер-методи є занадто великим тягарем. BTW; Ви можете серіалізувати та аналізувати 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". Якщо є декілька джерел, можливо, краще скористатися строфіфікацією для стандартизації даних.
Єлгаб

Це дуже гарна відповідь. Добре використовувати 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.