postMessage 解决不同源的传值

843 阅读2分钟

该方法是HTML5引入的API,可以通过异步方式实现跨源通信多用于窗口间数据通信。它提供了一种受控机制来规避不同源脚本无法通信的限制。

postMessage(data,origin)方法接受两个参数

  1. data:要传递的数据,

html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到,部分浏览器只能处理字符串参数,所以传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。

  1. origin:字符串参数,指明目标窗口的源

协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,someWindow.postMessage()方法只会在someWindow所在的源(url的protocol, host, port)和指定源一致时才会成功触发message event,当然也可以将参数设置为"*",someWindow可以在任意源,如果要指定和当前窗口同源的话设置为"/"

示例解读

主页a地址(http://localhost:3000) 页面b地址(http://localhost:8082)

1 主页a与引用的iframe页面b的通信

主页a 代码如下:

js:
    // 信息发送
  const sendPost = () => {
    const iframeWin = window.frames[0] ||  document.getElementById("otherPage").contentWindow;  
    const messageValue = document.getElementById("message").valuesetTimeout(() => {
      iframeWin.postMessage(messageValue, 'http://localhost:8082')
      },1000)
  }
  
  // 信息接收
  window.addEventListener("message", function( event ) {
    const data = event.data;
    console.log('data react base----->',data);
  })
 
html:
      <input type="button" value="发送" onclick="sendPost" />
      <iframe src="http://localhost:8082/" id="otherPage" />
      <textarea id="message" />

页面b (http://localhost:8082) 代码如下:

window.addEventListener("message", function( event ) {
  console.log('event----->',event);
  window.top.postMessage({name: 'hh'}, "http://localhost:3000/")
})

2 主页面a 通过open打开页面b的通信

主页a代码如下:

js:
    // 信息发送
  const sendPost = () => {
    const openWin = window.open('http://localhost:8082');  
    const messageValue = document.getElementById("message").valuesetTimeout(() => {
      openWin.postMessage(messageValue, 'http://localhost:8082')
      },1000)
  }
  
  // 信息接收
  window.addEventListener("message", function( event ) {
    const data = event.data;
    console.log('data react base----->',data);
  })

页面b 代码如下:

 const msg = {
   name: "B"
 }
 const opener = window.opener
 opener.postMessage(msg, "http://localhost:3000")

使用场景: 使用postMessage让 iframe自适应高度