绝大部分的场景你并不需要localStroage

发布于:2024-05-02 ⋅ 阅读:(28) ⋅ 点赞:(0)

前言

在实际业务开发中,有很多localStroage的使用场景,如:用户偏好设置、购物车信息、用户信息等等,如果只是把网站的主题色,就像使用暗黑还是明亮模式的信息存在localStroage里也还好,毕竟不涉及敏感信息,就像umi的官网一样,本地存储存了主题偏好、github stars这些信息。

image.png

或者是像掘金Web端,通过localStorage来保存用户的搜索历史作持久化。

image.png

这样即使我懂技术,把这个存储删了也无所谓,只是我的搜索历史被清了而已。

但在很多场景下,我发现会有同学把用户信息、ID、或者是会话鉴权的token存在localStroage中,这其实是很危险的技术方案。

处理方案

我们举个例子,例如有这样一段代码:

  useRequest(getUserInfo, {
    onSuccess: (res) => {
      res?.success && localStorage.setItem('userInfo', res.data)
    }
  })

其实没啥问题,也很方便,拿用户信息也是一段代码就可以解决:

localStorage.getItem('userInfo');

但有没有什么更好的方案?在满足方便的情况下,不要让用户信息暴露在浏览器中?其实用JavaScript原生的能力就很简单,我们把用户信息考虑存到应用的缓存中即可,缓存也并不是什么高科技,只要是一个对象,就可以实现缓存,我们在项目中新建一个文件,与页面组件隔离开,放在/src/common/cache.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];
}

再改造一下最前面的版本代码:

useRequest(getUserInfo, {
    onSuccess: (res) => {
      res?.success && setCache('userInfo', res.data);
    }
  })

读起来也很方便,一段代码也可以解决,甚至还更少:

const user = getCache('userInfo');

并且这样有什么好处呢?

  1. 信息可控,存localStorage中,通常如果用户懂技术,把本地存储清掉,你的大部分业务都需要重新走一遍登录,甚至会给你的系统带来一些隐藏bug;
  2. 性能更好,基于内存的缓存读写速度很快,因为直接操作的是内存中的对象,而localStorage是基于磁盘的,速度会慢一些;
  3. 该内存缓存仅存活于页面生命周期内,页面刷新后会丢失,对于那些不需要持久化的数据来说,使用内存缓存更合理;
  4. 安全,可以避免XSS攻击;

但也有坏处,有些必要的持久化场景只能由localStorage,就比如最早说到的网站主题,如果需求是当用户退出网站,下次进来可以根据记忆化显示,那cache就无法满足,或是一些对时效性有要求的场景,我们都应该遵从本地存储,但在一些应用周期通常只会set一次,get多次的场景,就可以使用cache的方案。

如果喜欢我的文章或者想上岸大厂,可以关注公众号,将不定期关注推送前端好文、分享就业资料秘籍,也希望有机会一对一帮助你实现梦想。


网站公告

今日签到

点亮在社区的每一天
去签到