实现一个响应式的本地存储localStorage

一、不足之处

经常用localStorage的朋友可能都知道,它是一种在用户浏览器中存储数据的机制。虽然它很有用,但也存在一些不足之处:

1.存储数据类型限制

localStorage只能存储字符串类型。这意味着我想要存储对象等数据,还需要使用JSON.stringify()方法将其转换为字符串,在读取数据时,再使用JSON.parse()方法将字符串转换回原来的数据类型。 同时如果我存储的是数字100,读取出来的却是字符串'100',这就改变了原有数据类型了。

2.存储数据明文易暴露

因为localStorage在浏览器中存储的是未经任何处理的明文,任何具有访问该浏览器权限的人都可以查看和修改这些数据。这对于存储敏感信息(如用户密码、信用卡号等)来说是非常不安全的。

3.数据同步不方便

对于一个需要频繁同步状态到本地存储的应用,localStorage经常需要处理数据的格式转换和存取。当变量的状态变化多了,每次都要在变量状态变化后调用方法同步这个变化到存储中,显得并不那么方便。

4.跨标签页数据无法实时同步

如果用户开启多个标签页,不经意间将其中一个标签页localStorage中设置改变了,其他标签页无法实时得知变化。这就造成了业务逻辑可能按旧值运行,造成业务逻辑的混乱。

二、 解决方案

基于以上几点,我开始设想构建一个库(liveStorage),它可以操作locolStorage``sessionStorage``cookie等存储媒介,同时解决以上4点不足之处。基于此,我挨个介绍下这个库的处理方式。

1.解决存储数据类型限制

解决数据类型限制最主要的步骤就对不同数据进行识别标识,再经过序列号处理后存储,当读取的时候根据标识逆向还原即可。 由于对象的值和数组的元素存在诸多不可被直接序列号的值,想要存储需要遍历值,将字面量特殊处理后再将对象进行序列号。对象的处理需要递归进行,因为难保某个对象值本身就是对象。

Number,BigInt,Boolean,RegExp,Date,Symbol等类型可以直接调用toString方法序列号; Map类型可以直接调用Array.from转化成数组;Undefined,Null直接用字符串代替即可。

2.解决明文暴露问题

将序列化玩的明文通过一系列自定义的编码操作进行'加密'。前端的加密虽然并不是绝对安全的,但它在一定程度上提高了对方直接破解的难度。同时可以添加多层转码操作,增加其复杂性。 对此,我以下几层简单的编码方式:

encodeURIComponentdecodeURIComponent实现中文字符编码和ASCII字符序列转换;

btoaatob实现ASCII字符序列和Base64字符串转换;

以上两组方法为语言内置的转码函数,比较容易被猜测出来,还需要内部添加动态化的词典再次做映射等处理,这样确保不那么快被猜出来。

3.实现数据同步问题

对于数据同步,最轻松的方式还是能像React和Vue那样的数据响应式,通过Proxy对数据进行代理,开发者对数据状态进行变化的时候即可通过代理的setter方法自动调用内部方法,实时将数据同步到本地存储中。在Vue中rel()直接将数据进行响应式处理,而我调用自己的watchItem()方法也对数据进行响应式处理并已经直接和locaLStorage进行绑定了。可以说它打通了三端的关联:数据、节点和localStorage。

javascript 复制代码
// 和input进行数据双向绑定,同时同步到本地存储(localStorage)中
let data = liveStorage.watchItem('username','Michael',{
    'mount':'input[name="username"]'
});
// 改变数据的值,即可实时更新本地存储(localStorage)
data.value = 'Jafferson';

由于直接量无法进行代理,可以将此赋值到临时对象中,用.value访问,这样就解决了代理的问题了。(用惯了Vue的孩子们都懂的,直接量需要用.value访问)

4.多标签页间数据同步方案

localStorage仅有方法调用,常规的使用中缺少事件驱动。我们需要增加事件处理,通知每个标签页本地存储中的数据变动了,让它们及时更新状态。

因为localStorage和sessionStorage都是Storage的实例化对象,可以通过storage事件监听其变化。

javascript 复制代码
window.addEventListener('storage',function(event){
...
});

传统的cookie是通过document.cookie进行操作的,并没有直接的事件,但现在已经有新的操作cookie的方式啦!

cookieStore是现代 JavaScript 中用于操作浏览器 Cookie 的 API ,它在浏览器环境中提供了一种更为灵活和强大的方式来管理 Cookie。cookieStore可以通过change事件监听cookie内容变化。

javascript 复制代码
cookieStore.addEventListener('change',function(event){
...
});

对于数据在多标签中同步的好处,我写了一个简单的Demo,你可以同时打开多个标签页,修改表单项。看其他标签页中表单项是否可以实时变化。 多标签页数据变化演示

三、 我的开源项目

开源仓库:github.com/mumuy/lives...

文档说明:passer-by.com/livestorage...

表单演示:passer-by.com/livestorage...

相关推荐
阿珊和她的猫4 小时前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
加班是不可能的,除非双倍日工资8 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi9 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip9 小时前
vite和webpack打包结构控制
前端·javascript
excel9 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国10 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼10 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy10 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT10 小时前
promise & async await总结
前端
Jerry说前后端10 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化