跨页面(tab/window)通信的几种方法
今天开发一个功能遇到一个需求,在页面 A 点击查看详情后在页面 B 进行审核,审核后页面 B 关闭,然后刷新页面 A 的数据。思路大概就是:
使用 webSocket
进行通讯
但是这样,工作量是巨大的,而且还需要后端支持。太麻烦了,对于我这种懒人来说,直接就放弃了。
写个定时器,不断检查 Cookies
的变化
然后在stackoverflow看到一个方案,大致思路是:
- 在页面A设置一个使用
setInterval
定时器不断刷新,检查Cookies
的值是否发生变化,如果变化就进行刷新的操作。 由于
Cookies
是在同域可读的,所以在页面 B 审核的时候改变Cookies
的值,页面 A 自然是可以拿到的。
这样做确实可以实现我想要的功能,但是这样的方法相当浪费资源。虽然在这个性能过盛的时代,浪费不浪费也感觉不出来,但是这种实现方案,确实不够优(zhāng)雅(bī)。
localStorage
的事件
后来发现 window
有一个 StorageEvent ,每当 localStorage
改变的时候可以触发这个事件。(这个原理就像你给一个DOM
绑定了 click
事件,当你点击它的时候,就会自动触发。)也就是说,我给 window
绑定这个事件后,每当我改变 localStorage
的时候,他都会触发这个事件。
1 | window.addEventListener('storage', function (event) { |
这个回调中的
event
与普通的EVNET,基本差不多,但是它比其他的event
多了如下几个属性:属性 | 描述 |
---|---|
key | 受影响的 localStorage 的 key |
newValue | 新的值 |
oldValue | 旧的值 |
url | 触发此事件的url |
每当一个页面改变了 localStorage
的值,都会触发这个事件。也就是说可以很容易的通过改变 localStorage
的值,来实现浏览器中跨页面( tab / window )之间的通讯。记住这个事件只有在 localStorage
发生改变的时候才会被触发,如果没改变则不会触发此事件。
1 | localStorage.setItem('update',1); //触发 |
在使用的时候务必注意这一点。
最终实现代码:
1 | //页面 A |