如何使用 HTML5 的 postMessage API 实现跨域通信?

推荐答案

使用 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. 工作流程

  1. 发送方: 通过 iframewindow.open() 等方式打开一个跨域的页面,并在需要的时候调用 postMessage() 发送消息。
  2. 接收方: 监听 message 事件,并在事件处理函数中验证消息来源 (origin),然后处理消息数据 (data)。
  3. 可选的回应: 如果需要,接收方可以使用 event.source.postMessage() 发送回应给发送方。

5. 应用场景

  • 跨域 iframe 通信
  • window.open() 打开的窗口之间的通信
  • Web Workers 和主线程之间的通信

6. 示例代码解析

  • 发送方 ( http://domain1.com/index.html )
    • 创建了一个 iframe 元素,指向 http://domain2.com/iframe.html
    • 按钮点击事件中,通过iframe.contentWindow获取iframewindow对象,然后使用postMessageiframe发送消息。
  • 接收方 ( http://domain2.com/iframe.html )
    • 监听 window 对象的 message 事件。
    • 在事件处理函数中,首先验证消息的 origin,确保消息来自 http://domain1.com
    • 如果消息的 actiongetData,将消息内容显示在页面上,并且使用 event.source.postMessage() 发送回应。
纠错
反馈