第169题:从页面 A 打开一个新页面 B,B 页面关闭(包括意外崩溃),如何通知 A 页面?
据我所知,A、B 页面通信方式有:
- url 传参
- postmessage
- localStorage
- WebSocket
- SharedWorker
- Service Worker
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 第170题:什么变量是存储在堆/栈?
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
本题是 html 页面通信题,可以拆分成:
A 页面打开 B 页面,A、B 页面通信方式
据我所知,A、B 页面通信方式有:
url 传参
url 传参数没什么可说的
B:
A 页面通过 url 传递参数与 B 页面通信,同样通过监听 hashchange 事件,在页面 B 关闭时与 A 通信
postmessage
postMessage
是h5
引入的 API,postMessage()
方法允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档、多窗口、跨域消息传递,可在多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案,简直不要太好用A 页面打开 B 页面,B 页面向 A 页面发送消息:
localStorage
注意:
localStorage
仅允许你访问一个Document
源(origin)的对象Storage
;存储的数据将保存在浏览器会话中。如果 A 打开的 B 页面和 A 是不同源,则无法访问同一Storage
WebSocket
基于服务端的页面通信方式,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种
SharedWorker
SharedWorker
接口代表一种特定类型的 worker,可以从几个浏览上下文中访问,例如几个窗口、iframe 或其他 worker。它们实现一个不同于普通 worker 的接口,具有不同的全局作用域,SharedWorkerGlobalScope
。Service Worker
Service Worker 是一个可以长期运行在后台的 Worker,能够实现与页面的双向通信。多页面共享间的 Service Worker 可以共享,将 Service Worker 作为消息的处理中心(中央站)即可实现广播效果。
B 页面正常关闭,如何通知 A 页面
页面正常关闭时,会先执行
window.onbeforeunload
,然后执行window.onunload
,我们可以在这两个方法里向 A 页面通信B 页面意外崩溃,又该如何通知 A 页面
页面正常关闭,我们有相关的 API,崩溃就不一样了,页面看不见了,JS 都不运行了,那还有什么办法可以获取B页面的崩溃?
全网搜索了一下,发现我们可以利用 window 对象的
load
和beforeunload
事件,通过心跳监控来获取 B 页面的崩溃使用 load 和 beforeunload 事件实现崩溃监控过程如下:
图片来自:https://zhuanlan.zhihu.com/p/40273861
这个方案巧妙的利用了页面崩溃无法触发 beforeunload 事件来实现的。
在页面加载时(load 事件)在 sessionStorage 记录 good_exit 状态为 pending,如果用户正常退出(beforeunload 事件)状态改为 true,如果 crash 了,状态依然为 pending,在用户第2次访问网页的时候(第2个load事件),查看 good_exit 的状态,如果仍然是 pending 就是可以断定上次访问网页崩溃了!
但有一个问题,本例中用 sessionStorage 保存状态,在用户关闭了B页面,sessionStorage 值就会丢失,所以换种方式,使用 Service Worker 来实现:
基于以上几点优势,完整设计一套流程如下:
代码如下:
参考:
原文
b.unload
postmassage消息通信