近期组内招人面试,在问问题的过程中提到了 localStorage 和 sessionStorage, 因为在开发 Electron 的过程中经常使用 localStorage 来存储数据,方便多个窗口共享,就顺便问了一下 sessionStorage 是否也可以,印象里是不可以的,面试者给我的答案是同源情况下是可以的。我也不确定,于是整理如下。
先总结一个第一个问题, localStoage 和 sessionStorage 的区别? 以下是 chatgpt 给的答案,我觉得很准确,就直接引用了
localStorage和sessionStorage是HTML5提供的两种客户端存储数据的方式。 它们的主要区别在于数据的生命周期和作用域。 localStorage的数据在浏览器关闭后仍然保留,因此具有长期存储的特性。它的作用域是在同一域名下的所有页面共享,即使是不同的标签页或窗口也可以访问相同的数据。 而sessionStorage的数据只在当前会话(即当前标签页或窗口)中有效。当会话结束时,数据将被清除。它的作用域限定在当前标签页或窗口,不同的标签页或窗口之间无法共享数据。
上述引用直接把标题的答案给了出来, sessionStorage 在不同的标签页和窗口之间无法共享数据,那真的是这个样子的吗?我们写 demo 验证一下
使用 react 搭建一个项目,配置两个路由, /about
和 /inbox
<Router>
<Routes>
<Route path="/" element={<App></App>} />
<Route path="/about" element={<About></About>} />
<Route path="/inbox" element={<Inbox></Inbox>} />
</Routes>
</Router>
<About>
组件实现如下, 只有一个方法, 读取 sessionStorage 和 localStorage
function About() {
const getStorage = () => {
console.log('sessionStorage', sessionStorage.getItem('session-name'));
console.log('localStorage', localStorage.getItem('local-name'));
}
return (
<div>
<h2>About</h2>
<button onClick={getStorage}>获取 storege</button>
</div>
);
}
<Inbox>
组件实现如下, 有三个方法,分别是设置、修改、清空 storage, 两种打开新 tab 的方式,一种是 window.open, 一种是 a 链接
function Inbox() {
const setStorage = () => {
sessionStorage.setItem('session-name', 'yach');
localStorage.setItem('local-name', 'yach');
}
const modifyStorage = () => {
sessionStorage.setItem('session-name', 'yach-modify');
localStorage.setItem('local-name', 'yach-modify');
}
const clearStorage = () => {
sessionStorage.clear();
localStorage.clear();
}
const onOpen = () => {
window.open('http://localhost:3000/#/about')
}
return (
<div>
<h2>Inbox</h2>
<button onClick={setStorage}>设置 storege</button>
<button onClick={modifyStorage}>修改 storage</button>
<button onClick={clearStorage}>清空 storage</button>
<button onClick={onOpen}>window.open</button>
{/* <Link to='/about' target="_blank">link</Link> */}
<a href="http://localhost:3000/#/about" target="_blank" rel="noreferrer">a</a>
</div>
);
}
demo 已经写完, 那我们就开始验证吧
- 同时打开两个 tab,分别加载 /about 和 /inbox, inbox 设置storage, about 获取, 结果如下
sessionStorage null localStorage yach
此处可以得出结论, sessionStorage 数据在多窗口和多 tab 下不共享
- 先打开 /inbox, 设置一下 storage, 在通过 window.open 打开 /about 获取, 结果如下
sessionStorage yach localStorage yach
这次就能获取到, 那到底能不能共享呢? 经过网上查阅得出如下结论
在一个新的 tab 或者窗口打开页面就会创建一个具有顶级浏览器上下文的新 session
即 sessionStorage 不可以在多个窗口或者 tab 间共享数据,但是当新的页面是通过 window.open 打开的,那么新的页面就会复制上一个页面的 sessionStorage 到新的页面中。
有人说通过链接方式打开,也会复制一份新的 sessionStorage, 通过上面 demo 试了一下,发现不行。目前只有通过 window.open 打开新页面会复制一份新的 sessionStorage