html5 Storage存取的坑
问题
今天因为同事在做一个微信的小程序开发,问了我些关于storage的问题,原来觉得storage挺好用的,对于不必放在数据库里有需要持久化储存的数据可以放在localStorage里,对于一些需要根据session来储存的数据可以储存在sessionStorage,但是在使用storage的时候遇到个很棘手的问题。
Storage的存取格式可能不统一!!!
为了说明这个问题,我写一段比较简单的代码,来做storage的存取,目的为存取一个数组
localStorage.setItem("listData",[1,2,3])
console.log(localStorage.getItem("listData"))
打印出来为
1,2,3
取出来为一个字符串,但是这样还好对吧,我们还是能用eval(“(” + str + “)”)把它转换为数组,或者用split(“,”),但是如果不注意存取前后的类型不一,可能会发生一些匪夷所思的问题,js是动态的弱类型语言,它不会告诉你这里类型不一。
上面那个情况发现了还是能解决,但是再看这一种情况,上面是存入的整型数组,现在我存入一个JSON数组会是怎样。
localStorage.setItem("listData",[{hello:"world"},{hello:"world"}]);
//let listData = eval("(" + localStorage.getItem("listData") + ")");
let listData = localStorage.getItem("listData").split(",")
console.log(JSON.parse(listData[0]));
你会发现取出来的形式是这样
[object Object],[object Object]
现在eval的方式不管用了,那我们用split的方式把它转换为数组,里面的每一个元素都是一个[object Object]形式的字符串,这样不管你怎样都不能将它转换为JSON了,因为它不是JSON形式的字符串你也不能调用JSON.parse。
解决方法
既然不能调用JSON.parse,那我们就在装入Storage的时候把它用JSON.stringify转成JSON形式的字符串。这样的方法显然是可行的。
localStorage.setItem("listData",JSON.stringify([{hello:"world"},{hello:"world"}]));
console.log(JSON.parse(localStorage.getItem("listData"))[0]);
总结一下,这样的坑的出现,在于storage内部是以(string,string)的键值对来储存的,不可避免的是根据键取出来的值是string类型的,想要类型统一,第一种是在存入的时候就转为字符串,这种相对安全,第二种是在取出的时候转换为原来的类型,上面也看到了,第二种是不安全的。