最近我需要将大型JSON对象保存在localStorage中。
首先,是的,它们确实保留了Unicode编码。但不要尝试将类似于对象的东西直接保存到本地存储中。它需要被转换成字符串。
以下是我在将对象转换为字符串之前使用的一些压缩技术(在我的情况下效果很好):
任何数字都可以通过执行 (+num).toString(36) 将其从10进制转换为36进制。例如,数字48346942将变为"ss8qm",其中(包括引号)少了1个字符。可能添加引号实际上会增加字符数。因此,数字越大,收益越好。要将其转换回来,您需要执行类似于 parseInt("ss8qm", 36) 的操作。
如果您要存储一个具有任何重复键的对象,最好创建一个查找对象,其中将缩短的键分配给原始键。例如,为了举例说明,如果您有:
{
name: 'Frank',
age: 36,
family: [{
name: 'Luke',
age: 14,
relation: 'cousin'
}, {
name: 'Sarah',
age: 22,
relation: 'sister'
}, {
name: 'Trish',
age: 31,
relation: 'wife'
}]
}
然后您可以将其制作成:
{
o: {
n: 'Frank',
a: 36,
f: [{
n: 'Luke',
a: 14,
r: 'cousin'
}, {
n: 'Sarah',
a: 22,
r: 'sister'
}, {
n: 'Trish',
a: 31,
r: 'wife'
}]
},
l: {
n: 'name',
a: 'age',
r: 'relation',
f: 'family'
}
}
再次强调,这对于大小和重复性都有好处。在我的情况下,它非常有效。但这取决于主题。
所有这些都需要一个缩小函数和一个扩展函数。
此外,我建议创建一个用于存储和检索本地存储数据的类。我遇到了存储空间不足的问题。因此写入会失败。其他站点也可能写入本地存储,这可能会占用一些空间。有关更多详细信息,请参见此帖子。
在我构建的类中,我首先尝试删除具有给定键的任何项。然后尝试setItem。这两行代码都包含在try catch中。如果失败,则假定存储已满。然后它将清除localStorage中的全部内容,以尝试为其腾出空间。然后,在清除之后,再次尝试setItem。这也被包装在try catch中。因为如果字符串本身大于localStorage可以处理的大小,则可能会失败。
编辑:此外,您将经常遇到许多人提到的LZW压缩。我已经实现了它,并且对于小字符串它很有效。但是对于大字符串,它将开始使用无效字符,导致数据损坏。因此,请小心,并且如果您走这条路,请进行测试、测试和测试。
localStorage
中的内容都应该按照存储时的方式返回。但是由于没有人知道,我一直在使用base64编码。 - KARASZI Istvánあ
的字符串测试了本地存储,其中あ
是 Unicode 平假名 A,但它无法保存该值(在 Google Chrome 中)。如果它不是 Unicode,那它会是什么?ASCII?拉丁语系列? - invisible bob