storage事件仅在同源其他标签页修改localStorage时触发,当前页不响应自身操作;需用localStorage而非sessionStorage;推荐用统一key封装JSON消息实现解耦通信。

JavaScript 通过 storage 事件监听 localStorage 或 sessionStorage 的变化,从而实现同源下多个标签页之间的简单通信。注意:该事件**只在其他标签页触发存储变更时触发**,当前页面调用 setItem 不会触发自身的 storage 事件。
监听 storage 事件的基本写法
使用 window.addEventListener('storage', callback) 即可监听。回调函数接收一个 StorageEvent 对象,包含关键属性:
-
key:被修改的键名(删除时为
null) -
oldValue:修改前的值(首次设置或跨浏览器初始写入时为
null) -
newValue:修改后的值(
removeItem时为null) - url:触发变更的页面 URL
-
storageArea:发生变更的存储对象(
localStorage或sessionStorage)
示例:
<script><br> window.addEventListener('storage', (e) => {<br> if (e.key === 'userStatus') {<br> console.log('状态更新:', e.oldValue, '→', e.newValue);<br> if (e.newValue === 'loggedOut') {<br> // 当前标签页执行登出逻辑(如清空本地状态、跳转)<br> }<br> }<br> });<br> </script>必须用 localStorage,不能用 sessionStorage
storage 事件**仅对 localStorage 有效**。虽然规范中也提到 sessionStorage,但所有主流浏览器(Chrome、Firefox、Safari、Edge)均不支持监听其变更事件。所以多标签通信务必使用 localStorage。
补充说明:
– 同一域名下的所有标签页共享同一个 localStorage;
– sessionStorage 是每个标签页独立的,天然不共享,也不触发跨标签 storage 事件。
触发事件的前提和常见陷阱
- 必须是同源页面:协议、域名、端口完全一致;跨子域(如 a.example.com 和 b.example.com)不生效
-
当前页不会收到自己触发的事件:在 A 标签页调用
localStorage.setItem('x', '1'),只有 B、C 等其他同源标签页能收到事件,A 自己收不到 -
值必须真正改变才会触发:重复设置相同字符串(
setItem('k', 'v')两次)通常不触发事件(部分旧版 Safari 有例外,但不可依赖) -
无法监听 clear():调用
localStorage.clear()会触发事件,但此时key、oldValue、newValue全为null,需靠url或额外约定字段识别意图
实用通信模式建议
避免直接监听原始键,推荐封装一层「消息总线」机制:
- 统一使用一个 key(如
__msg_bus__),value 是 JSON 字符串,含type、data、timestamp等字段 - 每次发消息都更新这个 key,确保值变化(例如加毫秒时间戳或随机 ID)
- 各标签页监听该 key,解析后按 type 分发处理(如
'broadcast'、'syncConfig'、'logoutAll')
优点:解耦、可扩展、避免 key 冲突,也方便未来替换为 BroadcastChannel 等更现代方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











