Skip to main content

通信

面试一句话总结:前端通信主要分为同源页面间通信跨域/非同源页面通信以及客户端与服务端通信。同源页面推荐使用 BroadcastChannellocalStorage,跨源页面依赖 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):客户端发起请求,服务端如果没数据就“挂起”请求不返回,直到有数据了再返回并关闭连接,客户端接着发起下一次请求。(旧时代的妥协方案,现在少用)。