前言
在实际业务开发中,有很多localStroage
的使用场景,如:用户偏好设置、购物车信息、用户信息等等,如果只是把网站的主题色,就像使用暗黑还是明亮模式的信息存在localStroage
里也还好,毕竟不涉及敏感信息,就像umi
的官网一样,本地存储存了主题偏好、github stars这些信息。
或者是像掘金Web端,通过localStorage
来保存用户的搜索历史作持久化。
这样即使我懂技术,把这个存储删了也无所谓,只是我的搜索历史被清了而已。
但在很多场景下,我发现会有同学把用户信息、ID、或者是会话鉴权的token
存在localStroage
中,这其实是很危险的技术方案。
处理方案
我们举个例子,例如有这样一段代码:
js
useRequest(getUserInfo, {
onSuccess: (res) => {
res?.success && localStorage.setItem('userInfo', res.data)
}
})
其实没啥问题,也很方便,拿用户信息也是一段代码就可以解决:
js
localStorage.getItem('userInfo');
但有没有什么更好的方案?在满足方便的情况下,不要让用户信息暴露在浏览器中?其实用JavaScript
原生的能力就很简单,我们把用户信息考虑存到应用的缓存中即可,缓存也并不是什么高科技,只要是一个对象,就可以实现缓存,我们在项目中新建一个文件,与页面组件隔离开,放在/src/common/cache.ts
中,代码如下:
ts
// 本文件存储需要在非React组件使用的数据
import { UserDto } from 'types/types';
interface Cache {
user: UserDto;
}
const cache: Cache = {
user: {
userId: '',
userName: '',
userType: '',
avatarUrl: '',
},
};
export function setCache<T extends keyof Cache>(key: T, value: Cache[T]) {
cache[key] = value;
}
export function getCache<T extends keyof Cache>(key: T) {
return cache[key];
}
再改造一下最前面的版本代码:
ts
useRequest(getUserInfo, {
onSuccess: (res) => {
res?.success && setCache('userInfo', res.data);
}
})
读起来也很方便,一段代码也可以解决,甚至还更少:
ts
const user = getCache('userInfo');
并且这样有什么好处呢?
- 信息可控,存
localStorage
中,通常如果用户懂技术,把本地存储清掉,你的大部分业务都需要重新走一遍登录,甚至会给你的系统带来一些隐藏bug; - 性能更好,基于内存的缓存读写速度很快,因为直接操作的是内存中的对象,而
localStorage
是基于磁盘的,速度会慢一些; - 该内存缓存仅存活于页面生命周期内,页面刷新后会丢失,对于那些不需要持久化的数据来说,使用内存缓存更合理;
- 安全,可以避免
XSS
攻击;
但也有坏处,有些必要的持久化场景只能由localStorage
,就比如最早说到的网站主题,如果需求是当用户退出网站,下次进来可以根据记忆化显示,那cache
就无法满足,或是一些对时效性有要求的场景,我们都应该遵从本地存储,但在一些应用周期通常只会set
一次,get
多次的场景,就可以使用cache
的方案。
如果喜欢我的文章或者想上岸大厂,可以关注公众号「量子前端」,将不定期关注推送前端好文、分享就业资料秘籍,也希望有机会一对一帮助你实现梦想。