封装一个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页面处理(父页面):
加入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跨域交互的更多相关文章
- 解决Iframe跨域高度自适应,利用window.postMessage()实现跨域消息传递页面高度(JavaScript)
在iframe跨域引用高度自适应这块写的js方式都试了不管用,最终使用的是window.postMessage() 跨域获取高度 传递信息 1.首先,在主页面上使用iframe引入子页面:也就是A.h ...
- JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- 利用window.name+iframe跨域获取数据详解
详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...
- js iframe跨域访问
1.什么是跨域? 2.前台解决跨域几种方法 2.1 动态创建script 2.2 使用document.domain 2.3使用HTML5新属性postMessage 2.4 利用iframe和loc ...
- iframe跨域通信实战
"长时间不写文章,开头的方式总是那么出奇的相似",最近很忙,好久没写博客了啊(是不是?). 更换工作已经有三个月有余,这段三个月把过去三年没加过的班都加了一次.收获挺多,发现的问题 ...
- 关于iframe跨域实践
提要 项目中与到iframe子页面中需要通过top获取在父页面中的全局变量的需求,由于App部署的缘故,导致父页面和iframe子页面分别在不同的端口下,导致iframe跨域现象,通过查阅资料进行问题 ...
- 子页面iframe跨域执行父页面定义的JS方法
问题需求:父页面与子页面iframe跨域嵌套,子页面要触发父页面所定义的js方法.父子页面的数据传递. 下文中会用到一些文件:父页面: parent.html嵌在父页面的子iframe页面:child ...
- iframe 跨域问题解决方案 利用window.name+iframe跨域获取数据详解
详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...
- iFrame跨域的方式
4种通过iframe跨域与其他页面通信的方式 不同域下的iframe不能进行操作. 1.location.hash: 在url中,http://www.baidu.com#helloword的#hel ...
随机推荐
- JWT & JSON Web Tokens
JSON Web Tokens https://jwt.io json web token example https://jwt.io/introduction/ https://medium.co ...
- PIP & Python packages management
PIP & Python packages management $ python3 --version # OR $ python3 -V # Python 3.7.3 $ pip --ve ...
- shit mint-ui & navbar click event bug
shit mint-ui & navbar click event bug # Vue 2.0 npm install mint-ui -S // 引入全部组件 import Vue from ...
- API 注解 & Java API annotation
API 注解 & Java API annotation 注解 annotation
- Node.js & ES modules & .mjs
Node.js & ES modules & .mjs Node.js v13.9.0 https://nodejs.org/api/esm.html https://nodejs.o ...
- windows 内核模式读写内存
sysmain.c #pragma warning(disable: 4100 4047 4024) #pragma once #include <ntifs.h> #include &l ...
- GoEasy使用阿里云OSS出现的问题
前言:本人使用goeasy来实现微信小程序里面和其他人的im临时对话窗口,想要实现可以同时发送语音和视频.图片.表情包的话,就要通过goeasy关联到阿里云的存储对象. 报错:The OSS Acce ...
- CNN专访灵石CTO:Baccarat流动性挖矿能否持续?
近日,CNN记者Robert独家专访Baccarat的项目团队CTO STEPHEN LITAN,跟他特别聊了聊DeFi的近况. 以下是专访全文: Robert:推出Baccarat的契机是什么? S ...
- 「NGK每日快讯」12.22日NGK第49期官方快讯!
- 【原创】Linux虚拟化KVM-Qemu分析(十)之virtio驱动
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...