题 在sessionStorage中保存Javascript对象


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总是通过 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 拦截调用的方法,但它是一项繁琐的工作,因为我必须定义所有属性,而我的目标是不知道未来的属性。


117
2018-05-31 21:08


起源


我自己也想过这个。我想很多人都有。但我不认为getter和setter方法太过负担。 BTW;您可以使用JavaScript进行序列化和解析,MS最终支持与其他人相同的标准对象。像JSON和jQuery这样的软件包需求日子即将结束。 - Roger F. Gay
我想我没有看到这个限制。如果你只有琐碎的对象,那么使用JSON.stringify和JSON.parse可能看起来有点过分,但是如果你有大小合适的数据对象那么这两种方法正在为你做很多工作。 - Robusto
“我可以避免这种限制吗?”好像是个问题 - sonicblis
是否有限制,这个问题帮我解决了一个问题,谢谢。 - Matt West


答案:


您可以使用Web Storage API提供的访问器,也可以编写包装器/适配器。从你声明的问题与defineGetter / defineSetter听起来像写一个包装器/适配器对你来说太多了。

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


15
2018-05-31 21:28



对不起,如果我使用了一个“荒谬”的不恰当的词。将其替换为“可能非常有趣”。我认为webStorage是新网络最激动人心的改进之一。但是只保存值键映射中的字符串,我认为是一个限制。这似乎是一个饼干的续集。我知道存储是一个不仅适用于Javascript语言的规范,但序列化对象可能是一个有趣的改进。你怎么看? - Ferran Basora
如果JSON不够,您可以始终编写自己的对象序列化方法。 - Ryan Olds
甚至违反SO规则的最愚蠢的答案。 Downvoted。 - sidney


难道你不能'对你的对象进行'字符串化'然后使用 sessionStorage.setItem() 存储对象的字符串表示...然后在您需要时 sessionStorage.getItem() 然后使用 $.parseJSON() 让它退出?

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


91
2018-04-25 22:40



这对我有用。调用$ .parseJSON()后,我得到一个工作的Json对象 - Olafur Tryggvason
某些系统(如Web Api身份验证)以Object {propertyOneWithoutQuotes:“<value1>”,... propertyNWithoutQuotes:“<valueN>”}的形式返回对象,需要通过“stringify”。如果有多个来源,最好使用stringify来标准化数据。 - Jelgab
这是非常好的答案。最好使用JSON.stringify()来序列化对象并存储在sessionStorage中。然后,它使用$ .parseJSON()对字符串进行反序列化以获取对象。 - Thomas.Benz


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

var user = {'name':'John'};
sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.user);

60
2017-10-02 11:05





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

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');

6
2018-03-15 02:38



很好,但不适用于功能。 - RSG


使用案例:

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

5
2017-11-26 06:55



我认为javascript中最好的做法之一就是不要将你不拥有的对象原型化。使用Storage.prototype.setObj似乎是一个坏主意。 - britztopher
相信我 。除了Object对象本身之外,它是一个好主意 - Abdennour TOUMI
只需添加强制性..确保您不添加此原型代码 - 并且完全依赖它 - 而无需先检查浏览器是否支持它存储: if (typeof (Storage) !== "undefined"){ /* browser supports it */ } - JoeBrockhaus


    var user = {'name':'John'};
    sessionStorage['user'] = JSON.stringify(user);
    console.log(sessionStorage['user']);

2
2018-01-19 07:46





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


1
2018-05-23 19:20