通信
面试一句话总结:前端通信主要分为同源页面间通信、跨域/非同源页面通信以及客户端与服务端通信。同源页面推荐使用
BroadcastChannel或localStorage,跨源页面依赖iframe配合postMessage,而服务端通信则有轮询、SSE 和 WebSocket 等多种方案。
1. 同源页面跨页面通信
在现代前端开发中,经常会遇到“在浏览器打开了两个 Tab 页,如何让它们状态同步”的面试题。
BroadcastChannel(最推荐的现代方案):创建一个用于广播的通信频道,只要是同源的页面,都可以通过new BroadcastChannel('my_channel')监听到同一频道发出的消息,API 极简且是专门为多页面通信设计的。LocalStorage+storage事件:这是最经典、兼容性最好的方案。当一个页面修改了 localStorage 中的某个值时,其他同源页面会触发window.onstorage事件。SharedWorker:一种特殊的 Web Worker,可以被多个同源页面共享。它可以作为一个“中心处理器”来分发消息。- Service Worker:常用于 PWA,也可以作为中间层拦截请求和广播消息。
- IndexDB + 轮询:利用同源数据库作为共享存储,但需要结合定时器轮询,性能较差,一般不推荐。
2. 非同源页面跨页面通信
如果两个页面不同源(比如一个是 a.com,另一个是 b.com),直接通信会被同源策略拦截。
iframe作为桥梁 +postMessage:这是唯一标准且合法的跨源通信方案。- 核心原理:
a.com内嵌一个指向b.com的 iframe,然后通过iframe.contentWindow.postMessage(data, targetOrigin)将数据发送过去。 - 安全提示:一定要在
postMessage和监听message事件时,严格校验origin,防止恶意网页注入。
- 核心原理:
3. 客户端与服务端通信 (全双工/单向)
面试官常问:“除了 AJAX/Fetch 轮询,还有什么办法能让服务端向客户端推数据?”
- WebSocket:真正的全双工通信协议。建立连接后,客户端和服务端可以互相主动发消息。底层基于 TCP,且没有同源策略限制(自带跨域能力)。
- SSE (Server-Sent Events):单向通信协议。建立 HTTP 连接后,服务端可以源源不断地向客户端单向推送数据流(Stream)。非常适合 ChatGPT 这种“打字机”效果的流式响应场景,比 WebSocket 更轻量且原生支持断线重连。
- 长轮询 (Long Polling):客户端发起请求,服务端如果没数据就“挂起”请求不返回,直到有数据了再返回并关闭连接,客户端接着发起下一次请求。(旧时代的妥协方案,现在少用)。