173

SessionStorage 和 LocalStorage 允许在 Web 浏览器中保存键/值对。值必须是字符串,保存js对象不是小事。

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

现在,您可以通过将对象序列化为 JSON,然后将它们反序列化以恢复对象来避免此限制。但是 Storage API 总是通过setItemandgetItem方法。

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'

我尝试了defineGetteranddefineSetter方法来拦截调用,但这是一项乏味的工作,因为我必须定义所有属性,而我的目标是不知道未来的属性。

4

9 回答 9

130

解决方案是在 sessionStorage 上调用 setItem 之前对对象进行字符串化。

var user = {'name':'John'};
sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.user);
于 2015-10-02T11:05:03.060 回答
116

你不能'stringify'你的对象......然后sessionStorage.setItem()用来存储你的对象的字符串表示......然后当你需要它sessionStorage.getItem()然后用$.parseJSON()它来取回它?

工作示例http://jsfiddle.net/pKXMa/

于 2012-04-25T22:40:23.860 回答
24

您可以使用 Web Storage API 提供的访问器,也可以编写包装器/适配器。从您声明的defineGetter/defineSetter问题来看,编写包装器/适配器对您来说工作量太大。

老实说,我不知道该告诉你什么。也许您可以重新评估您对“可笑限制”的看法。Web Storage API 正是它应有的样子,一个键/值存储。

于 2011-05-31T21:28:41.743 回答
18

这是一个动态解决方案,适用于所有值类型,包括对象:

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');
于 2017-03-15T02:38:36.473 回答
7

用例:

 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))
    };
于 2014-11-26T06:55:52.013 回答
4
    var user = {'name':'John'};
    sessionStorage['user'] = JSON.stringify(user);
    console.log(sessionStorage['user']);
于 2016-01-19T07:46:23.873 回答
4

会话存储不能支持任意对象,因为它可能包含在页面重新加载后无法重建的函数文字(读取闭包)。

于 2018-05-23T19:20:11.167 回答
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)
})
于 2017-10-11T11:58:03.410 回答
1

您可以创建 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);
于 2020-03-27T20:05:59.433 回答