“我在做网页应用,需要存个主题偏好、填了一半的表单,或者一个登录凭证。我知道这些数据该放浏览器里,但接下来总得面对那个躲不开的选择:是塞进本地存储,丢进会话存储,还是烤块小饼干?”
这段独白几乎出现在每个前端开发者的职业生涯里。三个东西看起来都像存数据的盒子,可一旦用错,用户体验崩了、页面响应慢了,严重的还会捅出安全窟窿。咱们把这些浏览器存储机制拆开看看,搞清楚它们底层到底怎么运作、什么时候该用哪个、架构上又要做哪些取舍。
本地存储像你租的那间数字储物间。东西放进去,它就老老实实待在那里,除非你哪天想起来去把它删掉。存个主题偏好就是两行代码的事:一个setItem把"dark"塞进名叫theme的抽屉,回头要用的时候getItem取出来。这玩意儿持久得惊人——页面刷新还在,标签页关了还在,浏览器重启甚至电脑重启,它还在。容量按Web标准算相当慷慨,浏览器不同大概给5MB到10MB。它的活动范围被同源策略严格限定,协议、域名、端口必须完全一致,甲网站存的数据乙网站绝对碰不着。什么时候用它合适?界面状态,比如暗黑模式还是明亮模式、侧边栏展开还是收起——这类不敏感的用户偏好。性能优化,缓存一份静态的、不涉密的数据,比如国家代码列表,省得每次加载页面都去打API。草稿保存也是经典场景,没提交的博客文章或评论先存起来,浏览器突然崩了不至于欲哭无泪。
如果本地存储是储物间,那会话存储就是临时工作台。当你正埋头干一件具体活儿的时候,它特别好使,但只要你起身走出那个房间,台面上所有东西瞬间被清空。跟踪一个多步骤的结算进度,一行sessionStorage.setItem就能标记当前走到第三步。它的核心设计就一条:数据只在当前页面会话期间存活。而且它认标签页——同一个网址在标签页A打开,再在标签页B打开,两边各自拥有一套完全隔离的会话存储桶。关掉标签页,这部分数据永久消失。容量跟本地存储差不多,大概5MB。适用场景很明确:跨页面的流程引导,比如多步结算或注册表单,用户在“下一步”和“上一步”之间跳转时需要带数据过去。再有就是标签页专属的状态,比如数据看板上的临时筛选条件或搜索参数,不该因为用户新开一个标签页查别的东西就串过去。
小饼干才是客户端存储里的老资格。它不像本地存储那样手动删除才消失,寿命由服务器设定的过期时间精确掌控。每次向服务器发起请求,浏览器都会自动把对应域下的饼干打包带上,这也是它跟另外两种存储最本质的区别——数据不是安安稳稳躺在客户端等你来取,而是不断在客户端和服务器之间来回跑。这块机制决定了饼干天生适合做身份维持那类事,但也正因为每个请求都带,体积必须严格控制,否则带宽和性能会肉眼可见地恶化。饼干的容量小得可怜,通常只有4KB左右。安全性上它有专门的HttpOnly和Secure标记可用,前者禁止JavaScript触碰,后者强制只在加密连接中传输。相比之下,本地存储和会话存储都对客户端脚本完全敞开,存什么都得想清楚会不会被跨站脚本攻击一把抓走。
技术决策到最后,往往是在一堆约束里找那个最不坏的选择。这三种存储没有谁绝对更好,只有谁更匹配当前的场景边界:数据需要活多久、体积有多大、能不能让脚本随便碰、要不要跟着每个请求走。想清楚这几条,那个“到底放哪儿”的纠结自然就解了。
热门跟贴