这是近期个人在开发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页面处理(父页面):

加入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(父页面)发起请求还是比较麻烦。欢迎各位提出意见或建议。

封装一个postMessage库,进行iframe跨域交互的更多相关文章

  1. 解决Iframe跨域高度自适应,利用window.postMessage()实现跨域消息传递页面高度(JavaScript)

    在iframe跨域引用高度自适应这块写的js方式都试了不管用,最终使用的是window.postMessage() 跨域获取高度 传递信息 1.首先,在主页面上使用iframe引入子页面:也就是A.h ...

  2. JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  3. 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  4. js iframe跨域访问

    1.什么是跨域? 2.前台解决跨域几种方法 2.1 动态创建script 2.2 使用document.domain 2.3使用HTML5新属性postMessage 2.4 利用iframe和loc ...

  5. iframe跨域通信实战

    "长时间不写文章,开头的方式总是那么出奇的相似",最近很忙,好久没写博客了啊(是不是?). 更换工作已经有三个月有余,这段三个月把过去三年没加过的班都加了一次.收获挺多,发现的问题 ...

  6. 关于iframe跨域实践

    提要 项目中与到iframe子页面中需要通过top获取在父页面中的全局变量的需求,由于App部署的缘故,导致父页面和iframe子页面分别在不同的端口下,导致iframe跨域现象,通过查阅资料进行问题 ...

  7. 子页面iframe跨域执行父页面定义的JS方法

    问题需求:父页面与子页面iframe跨域嵌套,子页面要触发父页面所定义的js方法.父子页面的数据传递. 下文中会用到一些文件:父页面: parent.html嵌在父页面的子iframe页面:child ...

  8. iframe 跨域问题解决方案 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  9. iFrame跨域的方式

    4种通过iframe跨域与其他页面通信的方式 不同域下的iframe不能进行操作. 1.location.hash: 在url中,http://www.baidu.com#helloword的#hel ...

随机推荐

  1. Laravel Homestead 安装 使用教程详解!

    1 Laravel Homestead 1 安装: 1 下载: http://www.vagrantup.com/downloads.html 1 配置: 1 1 测试: 1 1 ********** ...

  2. js currying All In One

    js currying All In One 柯里化 refs https://juejin.im/post/6844903603266650125 xgqfrms 2012-2020 www.cnb ...

  3. free useful skills videos courses & tutorials

    free useful skills videos courses & tutorials website video courses https://realpython.com/ http ...

  4. chown -R & chmod 777 & chmod +x

    chown -R & chmod 777 & chmod +x https://linux.die.net/man/1/chown chown - change file owner ...

  5. Linux & SIGUSER1

    Linux & SIGUSER1 https://stackoverflow.com/questions/10824886/how-to-signal-an-application-witho ...

  6. 【java】ObjectOutputStream & ObjectInputStream 多次写入发生重复写入相同数据的问题

    今日份代码,解决 ObjectOutputStream 多次写入发生重复写入相同数据的问题 核心区别如下: package com.sxd.swapping.objoutputstream; impo ...

  7. MySQL数据库与NAVICAT安装与配置

    1.安装破解版的NAVICAT:https://www.cnblogs.com/yinfei/p/11427259.html 2.连接MYSQL 下载MYSQL并安装,配置环境变量 以管理员身份运行C ...

  8. Python序列之列表(一)

    在Python中,列表是一种常用的序列,接下来我来讲一下关于Python中列表的知识. 列表的创建 Python中有多种创建列表的方式 1.使用赋值运算符直接赋值创建列表 在创建列表时,我们直接使用赋 ...

  9. c#winform主题实现的一个方法

    winform的主题实现没有bs里面那么舒服,下面做了一个简单实现,记录一下. 1.一个接口,需要做主题的控件.窗体都要实现这个接口 /// <summary> /// 使用主题的控件.窗 ...

  10. idea没有错误提示的解决方法(一直处于错误分析中)

    仅作记录,以防再次发生却不记得. 原文链接:https://blog.csdn.net/a755199443/article/details/90084316 问题描述:idea没有自动报错.例如随便 ...