推荐答案
使用 HTML5 的 postMessage
API 实现跨域通信主要涉及两个部分:发送消息方和接收消息方。
发送消息方 (例如:http://domain1.com/index.html
)
-- -------------------- ---- ------- --------- ----- ------ ------ ------------------- ------- ------ ------- ---------------- ---------------------------------------------- ------- ----------------------------- -------- ----- ------ - --------------------------------------- ----- ---------- - -------------------------------------- ------------------------------------ -- -- - ----- ------------ - --------------------- ----- ------- - - ------- ---------- ----- ------ ---- -------- -- --------------------------------- ---------------------- -- ----- --- --------- ------- -------
接收消息方 (例如:http://domain2.com/iframe.html
)
-- -------------------- ---- ------- --------- ----- ------ ------ ------------------- ------- ------ ---- ----------------------- -------- ----- ----------- - --------------------------------------- ---------------------------------- ------- -- - -- ------------- --- --------------------- - --------------------- -------- ---- ------- --------- -------------- ------- -- ------ - ----- ------- - ----------- -- --------------- --- ---------- - --------------------- - -------- --------- - - ------------- -------- -------------------------- ------ -------- -------- -- ------------ -------------- - - --- --------- ------- -------
本题详细解读
1. postMessage()
方法
postMessage()
是 window
对象的一个方法,用于安全地实现跨域通信。它接受两个参数:
message
: 要发送的消息数据,通常是 JavaScript 对象或者字符串。targetOrigin
: 指定接收消息的窗口的域。可以是具体的域名 (例如:'http://domain2.com'
) 或*
表示接受来自任何域的消息,但出于安全考虑,不推荐使用*
。
2. message
事件
接收消息的窗口需要监听 message
事件来处理接收到的消息。event
对象包含以下属性:
data
: 发送方发送的消息数据。origin
: 发送消息的窗口的域。source
: 发送消息的窗口对象的引用,可以用来向发送方发送回应。
3. 安全考虑
- 验证
origin
: 接收方必须通过检查event.origin
来验证消息的来源,避免接收来自恶意网站的消息。 - 避免使用
*
: 在targetOrigin
中避免使用*
,尽可能指定具体的域名,以减少安全风险。 - 小心处理接收的数据: 接收到的数据应该被当成是不可信任的,并进行必要的验证和清理,防止 XSS 等安全漏洞。
4. 工作流程
- 发送方: 通过
iframe
或window.open()
等方式打开一个跨域的页面,并在需要的时候调用postMessage()
发送消息。 - 接收方: 监听
message
事件,并在事件处理函数中验证消息来源 (origin
),然后处理消息数据 (data
)。 - 可选的回应: 如果需要,接收方可以使用
event.source.postMessage()
发送回应给发送方。
5. 应用场景
- 跨域
iframe
通信 window.open()
打开的窗口之间的通信- Web Workers 和主线程之间的通信
6. 示例代码解析
- 发送方 (
http://domain1.com/index.html
)- 创建了一个
iframe
元素,指向http://domain2.com/iframe.html
。 - 按钮点击事件中,通过
iframe.contentWindow
获取iframe
的window
对象,然后使用postMessage
向iframe
发送消息。
- 创建了一个
- 接收方 (
http://domain2.com/iframe.html
)- 监听
window
对象的message
事件。 - 在事件处理函数中,首先验证消息的
origin
,确保消息来自http://domain1.com
。 - 如果消息的
action
为getData
,将消息内容显示在页面上,并且使用event.source.postMessage()
发送回应。
- 监听