将Javascript对象保存在sessionStorage中


152

SessionStorage和LocalStorage允许将键/值对保存在Web浏览器中。该值必须是一个字符串,并且save js对象并不简单。

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

如今,您可以通过将对象序列化为JSON,然后反序列化它们以恢复对象来避免这种限制。但是Storage API始终通过setItemgetItem方法传递。

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'

我已经尝试过defineGetterdefineSetter方法来拦截调用,但这是一项繁琐的工作,因为我必须定义所有属性,而我的目标是不知道将来的属性。


1
我自己已经想到了。我想很多人都有。但是我不认为getter和setter方法会带来太多负担。BTW; 您可以使用JavaScript进行序列化和解析,而MS最终将支持与其他所有人相同的标准对象。对诸如JSON和jQuery之类的程序包的需求即将终结。
罗杰F.盖伊2013年

1
我想我看不到限制。如果您仅拥有一些琐碎的对象,那么使用JSON.stringify和JSON.parse似乎有点过头了,但是如果您有大小适中的数据对象,那么这两种方法将为您完成很多工作。
Robusto

5
“我可以避免这种限制吗?” 似乎是一个问题
sonicblis 2014年

1
限制与否,这个问题帮助我解决了一个问题,所以谢谢。
马特·韦斯特

Answers:


19

您可以使用Web Storage API提供的访问器,也可以编写包装器/适配器。从您所定义的defineGetter / defineSetter问题来看,听起来像编写包装器/适配器对您来说是太多的工作。

老实说,我不知道该怎么说。也许您可以重新评估什么是“荒谬的限制”。Web Storage API就是键/值存储。


8
抱歉,如果我用不适当的单词加上“荒谬”。替换为“可能很有趣”。我认为webStorage是新Web最激动人心的改进之一。但我认为在值键映射中仅保存字符串是有限制的。好像是饼干的续集。我知道存储不仅是Java语言的规范,但是序列化对象可能是一个有趣的改进。你怎么看?
Ferran Basora 2011年

2
如果JSON还不够,您总是可以编写自己的对象序列化方法。
Ryan Olds

110

您能否不“字符串化”您的对象...然后使用它sessionStorage.setItem()来存储对象的字符串表示形式...然后在需要时sessionStorage.getItem()使用它,然后使用$.parseJSON()它来取回它?

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


这对我有用。调用$ .parseJSON()之后,我得到了一个工作的Json对象
Olafur Tryggvason

诸如Web Api身份验证之类的某些系统以Object {propertyOneWithoutQuotes:“ <value1>”,... propertyNWithoutQuotes:“ <valueN>”}的形式返回对象,这些对象需要经过“ stringify”。如果有多个来源,最好使用字符串化来标准化数据。
Jelgab 2015年

这是一个很好的答案。最好使用JSON.stringify()序列化对象并存储在sessionStorage中。然后,它使用$ .parseJSON()将字符串反序列化以获取对象。
Thomas.Benz

102

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

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

感谢您未链接解决方案
Luc-Olsthoorn '19

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



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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.