封装一个postMessage库,进行iframe跨域交互

这是近期个人在开发chrome插件时的其中一个小总结。还有很多没有总结出来。因为目前插件还在迭代中,(herry菌插件,用于B站C站),属于个人业余的一个小项目。还有很多功能没有实现,以及还需要再看能加上什么功能。

 

封装的postMessage库 herryPostMessage.js

(function (w) {
  //herry对象
  w.herry = {};
  //iframe的id
  if(!herry.iframeId) {
    herry.iframeId = 'iframe'
  }
  //父窗口名字
  if(!herry.parentName) {
    herry.parentName = '父窗口'
  }
  //子窗口名字
  if(!herry.childName) {
    herry.childName = '子窗口'
  }
  //跨域对象
  const messageObj = {};
  //父页面
  /**
   * 发送给子页面数据
   */
  const postMessage = (data, fn = null) => {
    const iframe = document.getElementById(herry.iframeId)
    iframe.contentWindow.postMessage(
      {
        name: herry.parentName, //父页面名字
        ...data,
      },
      "*"
    );
    messageObj[data.action] = fn;
  };
  /**
   * 监听子页面返回的数据
   */
   w.addEventListener(
    "message",
    (event) => {
      const { data } = event;
      if (data && typeof data === "object" && data.name === herry.childName) {
        messageObj[data.action](data);
      }
    },
    false
  );
  //子页面
  /**
   * 返回数据给父页面 参1=当前action 参2=返回的数据
   */
  const returnData = (action, data) => {
    top.postMessage(
      {
        name: herry.childName, //子页面名字
        action,
        data,
      },
      "*"
    );
  };
  /**
   * 监听父页面发送的数据
   */
   w.addEventListener(
    "message",
    async (event) => {
      const { data } = event;
      if (data && typeof data === "object" && data.name === herry.parentName) {
        if (herry.callback) {
          herry.callback(data)
        }
      }
    },
    false
  );
  herry.postMessage = postMessage;
  herry.returnData = returnData;
})(window);

 

使用这个库让a域名下获取b域名下的数据,即a发出请求,b返回给a数据a是父页面,b是子页面

使用:

域名a和b的页面上都需要引入herryPostMessage.js

a页面处理(父页面):

程序地带 https://www.yehe.org/

加入iframe(src是b域名的页面,需要设置一个id,一般也可以将iframe使用样式隐藏掉)。

<iframe
  src="//b.com/xxx.html"
  id="ifr"
  frameborder="0"
></iframe>

设置iframeId=上面的这个id:

herry.iframeId = "ifr";

发起请求(action是设置的一个请求名,在b页面中进行匹配用。后面的数据是携带给b页面用的参数。后面的res是b页面执行后的回调函数,可进行处理b返回的数据):

herry.postMessage({ action:'geta1', x: 1 }, (res) => {
  console.log(res.data);
});

 

b页面处理(子页面):

b页面的herry.callback通过action匹配执行,并做处理,通过herry.returnData将数据返回给a的回调函数。即实现了交互。

herry.callback = async (data) => {
  if (data.action === "geta1") {
    //...
    herry.returnData(data.action, { x: 2 });
  }
  //...
};

 

不过这种封装方式也不是特别好,有局限性,比如b(子页面)像a(父页面)发起请求还是比较麻烦。欢迎各位提出意见或建议。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Web 开发中,当网页中包含来自不同域名的 iframe(内嵌框架)时,由于浏览器的同源策略限制,iframe 之间的直接通信会受到限制。为了实现 iframe 之间的跨域通信,可以使用 postMessage 方法。 postMessage 是一种 HTML5 提供的跨文档消息传递机制,它允许在不同窗口或 iframe 之间发送消息。通过 postMessage,可以在不同域名之间进行安全的双向通信。 使用 postMessage 进行跨域通信的步骤如下: 1. 在发送消息的页面(发送方)中,使用 JavaScript 调用 postMessage 方法发送消息。该方法接受两个参数:要发送的消息和接收消息的目标窗口的源(origin)。目标窗口的源可以是具体的域名、协议和端口号,或者是通配符 "*" 表示任意源。 ```javascript var targetWindow = document.getElementById('target-frame').contentWindow; targetWindow.postMessage('Hello', 'https://target-domain.com'); ``` 2. 在接收消息的页面(接收方)中,监听 message 事件,通过 event.data 获取接收到的消息。在事件处理程序中可以对消息进行处理。 ```javascript window.addEventListener('message', function(event) { if (event.origin === 'https://source-domain.com') { console.log('Received message: ' + event.data); } }); ``` 通过这种方式,发送方和接收方可以进行跨域通信,并且可以在消息中传递复杂的数据结构。但要注意,为了确保安全性,应该在接收方对来自不同源的消息进行验证,以防止恶意代码的攻击。 需要注意的是,postMessage 方法只能在现代浏览器中使用,兼容性可能会有所差异。此外,在使用 postMessage 进行跨域通信时,也需要确保目标窗口(接收方)支持 postMessage 方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值