✅作者简介:大家好我是无处不楼台,是一个什么都会一点的大前端小白博主!
个人主页:无处不楼台的博客_CSDN博客-JavaScript学习,项目开发,node学习领域博主
系列专栏:知识体系梳理
如果觉得博主的文章还不错的话,请三连支持一下博主哦
目录
前言
同源页面间的跨页面通信
1、BroadCast Channel
创建
监听
发送消息
关闭
优点
缺点
2、Server Worker
缺点
3、localStorage
优点
缺点
优点
缺点
5、indexDB
6、window.open+window.opener
优点
缺点
非同源页面之间的通信
1、iframe+postMessage()
优点
缺点
结束语
首先,我们先要了解一下什么叫前端跨页面通信;
当我们在浏览器中打开很多页面时,如果我们对一个页面上的数据进行了修改操作,而跟这个数据相关的其他页面也能够实时的修改页面上的数据,这就叫做跨页面通信;
比如,在react-native中,用户打开的所有页面都存放在系统栈中,用户能看到的只是栈顶的那个页面,如果用户在修改栈顶数据时,栈底的页面如果跟这个数据有关系的话,我们希望它也可以实时的改变自身的数据;
下面,我们来梳理一下有哪些跨页面通信方案;
BroadcastChannel,就字面意思来言,叫做“广播频道”,官方文档说,该API是用于同源不同页面之间完成通信的功能
BoardCast Channel可以帮助我们创建一个用于广播的通信频道,当所有页面都监听同一频道时,其中某一个页面通过它发送的消息就会被其他所有页面收到;
const a=new BoardcastChannel(频道实例名字);
在这里接收了一个字符串作为name,用来识别这个channel;
这样的话,在其他页面就可以通过传入相同的name来使用同一个广播频道,这个name可以通过.name来获取;
a.onmessage=function(e){
console.log('receive:',e.data);
}
对于错误也可以绑定监听:
a.onmessageerror=function(e){
console.log('error:',e);
}
a.postMessage('hello');
a.close();
调用close方法之后,就会切断与BoardCast Channel的连接,浏览器才会尝试回收该对象;
✅实时通信,随时关闭频道,功能全面;
✅浏览器支持效果不好(IE都不支持)
Server Worker是一个可以长期运行在后台的worker,能够实现与页面的双向通信;
多页面的service worker可以共享,将service worker作为消息的处理中心,即可实现广播效果;
service worker跟BoardCast Channel相似之处在于两者都是使用了广播的方式完成跨页面通信;
而service worker不同的点在于,它本身不具备广播通信的功能,我们需要再配置service worker ,将其改造成消息中转站;
如何配置service worker这里就不多赘述;
✅浏览器支持度不高,开启service worker可能会导致浏览器的缓存数据大大增加(IE不支持)
我们经常会用到localstorage,在这里,我们需要注意的是它的storage事件;
当localstorage发生变化时,会触发storage事件。利用这个特性,我们在发送信息的时候,把信息写入到localstorage中;然后在各个页面中,我们监听storgae事件即可完成跨页面通信;
当某一个页面需要发送消息时,只需要使用setItem方法即可
✅浏览器支持效果好、API简单直观
✅ 可能因为localstorage清理不及时产生问题
shared worker接口代表一种特定类型的worker,可以在几个上下文中访问
如果要使sharedworker连接到多个不同的页面,这些页面必须是同源的;
同一个jurl只会创建一个shared worker,其他页面类使用同样的url创建的sharedworker,会复用已创建的worker
普通的worker之间是独立运行的,而且数据互不相同,而多个tab注册的shared worker可以实现数据的共享;
shared worker在实现跨页面通信时的问题在于,它无法主动通知所有页面,因此,我们会使用轮询的方式,来拉取最新的数据;
也就是说让页面主动获取最新的消息;
✅异步处理,不占用主线程;
✅IE不支持;
与shared worker相似,indexDB将数据储存起来,接收页面的轮询;
当我们使用window.open打开一个页面时,我们会建立起一个树形结构,当我们需要发送消息时,作为消息的发起方,一个页面需要同时通知它打开的页面和打开它的页面;
被打开的页面,可以通过window.opener来获取打开他的页面的引用;
这样每一个页面节点都肩负起来了传递消息额的责任;
但是这种方式存在一个问题:如果页面不是通过另一个页面的window.open打开的,例如直接在地址栏输入,或从其他网站链接过来,这个树状结构就不可行了;
✅实现简单,浏览器兼容性好
✅实现方式无法形成同一的解决方案,且存在强制刷新页面后失去关联页面导致无法通信;
上面说了有七种前端跨页面通信的方法,但是他们都受同源策略的限制。然而有时候,我们有两个不同域名产品线,也希望它们下面的所有页面能够无障碍地通信。
要实现这样的功能,可以使用一个用户不可见的iframe作为“桥”。由于iframe与父页面间可以通过postMessage();忽略同源限制,因此可以在每个页面中嵌入一个iframe,而这些iframe由于使用的是一个url,因此属于同源页面,其通信方式可以复用上面第一部分提到的各种方式;
页面与iframe通信非常简单,首先需要在页面中监听iframe发来的消息,做相应的业务处理,然后,当页面要与其他的同源或非同源页面通信时,会先给iframe发送消息;
iframe收到消息后,会使用某种跨页面通信技术在所有iframe间同步消息,例如使用BoardCast Channel;
✅点对点通信;
✅局限性较大;
明天继续肝!!!