引言:为什么需要在浏览器存东西?
想象一下你登录了一个网站,每次点击新页面,服务器都得重新问一遍"你是谁?",这体验简直灾难。因此,我们需要一种机制,在用户的浏览器里"存点小纸条",用来记录状态、偏好或其他信息。
这就是 Cookie、LocalStorage 和 SessionStorage 的用武之地。它们都是浏览器提供的客户端存储方案,但设计初衷和适用场景截然不同。选对了,体验丝滑;选错了,可能埋下bug甚至安全漏洞。
一、 Cookie:劳苦功高的"老大哥"
Cookie 是最早的浏览器存储机制,它的核心任务是与服务器通信。
- 存储形式 :经典的
key=value
键值对。一段小小的文本字符串。
js
// 存 - 只能直接设置字符串,一次只能设置一个键值对
document.cookie = "username=John Doe; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/";
// 取 - 会获取所有cookie,需要自己解析
const allCookies = document.cookie; // 得到 "username=John Doe; theme=dark"
console.log(allCookies);
// 删 - 通过设置过期时间为过去的时间
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
- 域名限制 :遵循同源策略 。只能被设置它的域名及其子域名(取决于
Domain
设置)访问。 - 存储位置与发送方式 :这是它最独特的点!Cookie 的数据存储在客户端 ,但每次发送 HTTP 请求时,只要请求的域名和路径匹配,浏览器就会自动将其放在请求头(Request Headers)的
Cookie
字段里发给服务器。这也是它和另外两位最本质的区别。 - 生命周期 :
- 会话期Cookie :不设置过期时间(
Expires
或Max-Age
),浏览器关闭就失效。 - 持久性Cookie:设置了过期时间,到时间才失效。可以存很久。
- 会话期Cookie :不设置过期时间(
- 跨页面/标签页 :可以。只要在同一浏览器且域名匹配,不同标签页可以共享Cookie。
- 容量 :很小,约 4KB。多了服务器每次处理那么多请求头,压力会很大。
- API :原生API比较难用,是
document.cookie
。存、取、删都需要自己拼接字符串。 - 关键特性与用途 :
- 核心用途 :会话状态管理(最经典的就是用户登录凭证Session ID)、个性化设置(如语言)、行为跟踪。
- 安全特性 :可以设置一些属性来增强安全:
HttpOnly
:禁止JavaScript读取,有效缓解XSS攻击(但无法完全防御)。Secure
:只在HTTPS协议下才发送Cookie。SameSite
:规定Cookie不能随跨站请求发送,是防御CSRF攻击的利器(值可为Strict
,Lax
,None
)。
js
// 设置一个安全的Cookie(仅HTTPS发送,JS无法读取)
document.cookie = "sessionId=abc123; Secure; HttpOnly; SameSite=Lax";
二、 LocalStorage:本地"大仓库"
HTML5带来了Web Storage API,LocalStorage 是其中的一员。它的设计目标很纯粹:在本地存更多、更持久的数据,且不参与服务器通信。
- 存储形式 :也是
key-value
键值对,但value可以是字符串(存对象需用JSON.stringify()
转换)。
js
// 存 - 可直接存字符串
localStorage.setItem('theme', 'dark');
// 存对象需转为JSON
localStorage.setItem('user', JSON.stringify({ name: 'John', id: 1 }));
// 取
const theme = localStorage.getItem('theme'); // 'dark'
const user = JSON.parse(localStorage.getItem('user')); // {name: 'John', id: 1}
// 删
localStorage.removeItem('theme');
// 清空
localStorage.clear();
-
域名限制 :严格遵循同源策略 。只有同一协议、域名、端口的页面才能访问。
-
存储位置与发送方式 :数据纯粹存储在本地 ,绝不会自动发送给服务器。这节省了大量不必要的网络流量。
-
生命周期 :永久有效 。除非用户手动在浏览器设置中清除,或者你用代码(
localStorage.clear()
)删除,否则数据会一直存在。 -
跨页面/标签页 :可以。同源的所有标签页和窗口都可以共享同一个LocalStorage。
-
容量 :大了很多,通常是 5MB 左右(不同浏览器有差异)。
-
API :非常简单易用!
javascript// 存 localStorage.setItem('myKey', 'myValue'); // 取 const data = localStorage.getItem('myKey'); // 删 localStorage.removeItem('myKey'); // 清空 localStorage.clear();
-
关键特性与用途 :
- 核心用途 :存储长期不变的本地数据。比如用户在没有登录时设置的主题、皮肤、网站的静态资源缓存、某些不敏感的用户偏好等。
三、 SessionStorage:单次会话的"草稿纸"
SessionStorage 和 LocalStorage 是亲兄弟,同属 Web Storage API,用法一模一样,但生命周期和作用域天差地别。
- 存储形式 :同 LocalStorage,
key-value
键值对。
js
// 用法和localStorage一模一样,只是换了个名字
sessionStorage.setItem('formData', JSON.stringify({ step: 2, name: 'Jane' }));
const data = sessionStorage.getItem('formData');
sessionStorage.removeItem('formData');
- 域名限制 :同 LocalStorage,严格遵循同源策略。
- 存储位置与发送方式 :同 LocalStorage,只存本地,不发服务器。
- 生命周期 :仅在当前浏览器标签页有效 。
- 刷新页面(F5)数据还在。
- 关闭标签页(或整个浏览器),数据立即被销毁。
- 在新标签页打开同一个网址,会创建一个全新的、独立的SessionStorage,无法访问之前标签页的数据。
- 跨页面/标签页 :绝对不行! 这是它和LocalStorage最大的不同。每个标签页的SessionStorage都是隔离的。
- 容量 :同 LocalStorage,约 5MB。
- API :和LocalStorage完全一样,只是把
localStorage
换成sessionStorage
。 - 关键特性与用途 :
- 核心用途 :存储一些一次性的、临时性的 数据。比如:
- 一个多步骤表单填写的临时内容,防止页面刷新后数据丢失。
- 单页应用(SPA)中某个组件的临时状态。
- 核心用途 :存储一些一次性的、临时性的 数据。比如:
总结与对比
为了更直观,我们用一个表格来总结三者的核心差异:
特性维度 | Cookie | LocalStorage | SessionStorage |
---|---|---|---|
本质 | 与服务器通信的载体 | 本地大规模存储的仓库 | 本次会话临时存储的草稿纸 |
生命周期 | 可设置过期时间,或浏览器关闭失效 | 永久有效,除非手动删除 | 仅当前标签页有效,关闭即删除 |
存储大小 | ~4KB | ~5MB | ~5MB |
是否随请求发送 | 是 (放在HTTP头中,影响性能) | 否 | 否 |
作用域 | 可跨标签页,可通过Domain 和Path 设置 |
同源的所有标签页可共享 | 仅限当前标签页 (同源也不同享) |
API易用性 | 差 (需自行拼接字符串) | 极佳 (简单键值对API) | 极佳 (同LocalStorage) |
它们的共同点:
- 都受同源策略限制。
- 都存储在客户端(浏览器)。
- 都容易被XSS攻击读取(HttpOnly Cookie除外),所以绝不能存储密码、密钥等敏感信息。
面试怎么聊?看这里!
如果面试官问你这个问题,他不仅想听你背区别,更想考察你的理解深度 和应用能力。
1. 基础题:"说说它们的区别。"
- 答法 :别干巴巴地背表格。可以先总述:"它们都是客户端存储,但设计目的不同。"然后挑最重要的生命周期、容量、是否随请求发送、作用域 这四点展开说,最后用一句话总结核心:"Cookie是为服务器通信而生,而Web Storage是为本地存储而生。"
2. 灵魂题:"有了LocalStorage,为什么还需要Cookie?"
- 答法 :抓住核心:"因为HTTP协议是无状态的。"服务器需要一种机制来识别连续请求是否来自同一用户。Cookie通过每次请求自动携带Session ID完美解决了这个问题,而LocalStorage的数据不会自动发给服务器,所以无法直接用于身份认证。
3. 场景题:"如何选择使用哪个?"
- 答法 :这能体现你的实践经验。
- 需要让服务器知道的信息 (登录token、用户ID) -> Cookie (并强调要设置
HttpOnly
和Secure
)。 - 需要长期存在本地的非敏感数据 (用户主题、配置) -> LocalStorage。
- 当前流程的临时数据 (多步表单、组件状态) -> SessionStorage。
- 需要让服务器知道的信息 (登录token、用户ID) -> Cookie (并强调要设置
4. 进阶题:"聊一下安全性吧。"
- 答法 :这能展示你的知识广度。
- XSS :三者都怕。别存敏感信息。
HttpOnly
Cookie能提供一层保护。 - CSRF :Cookie的"自动携带"特性导致它容易受到CSRF攻击。防御方法是使用CSRF Token 或设置Cookie的
SameSite
属性。 - 再次强调:敏感信息别往这里存!
- XSS :三者都怕。别存敏感信息。
希望这篇文章能帮你把这"三兄弟"理得明明白白,下次面试遇到这个问题,就能对答如流了!