Iframe父子窗口之间的跨域事件调用和传值
实现方案1:location.hash传值
父页面:parent.html(所在域:www.parent.com)
子页面:child.html(所在域:www.child.com)
要实现父子页面双向的事件调用和传值,需要多加一个代理页面,主要用于子页面调用父页面的方法
代理页面:proxy.html(所在域:www.parent.com)必须与父页面在同域下
父页面调用子页面方法(即事件通过父页面发起,在子页面中执行):
父页面中直接设置iframe的src中的hash值
parent.html:
var frameurl = "http://www.child.com/child.html"
document.getElementById("frameId").src=frameurl+"#action="+actionName+"&data="+dataJSONStr;
子页面中设置定时器监听hash的变化,监听到后直接执行该方法
child.html:
var currentHash = location.hash;
setInterval(function(){
var hash = location.hash.substring(1);
if(currentHash!==hash){
var action = ...;
var data = ...;
childFuncClass[action](data);
}
},1);
同样可以使用onhashchange事件监听到
子页面调用父页面方法(事件通过子页面发起,在父页面中执行)
在子页面child.html中添加一个iframe链接到上面所说的proxy.html,child.html中通过改变proxy.html的hash值,在proxy.html中监听hash变化事件,监听到以后直接调用parent.html中的方法(与父页面调用子页面方法一致)
proxy.html:
var currentHash = location.hash;
setInterval(function(){
var hash = location.hash.substring(1);
if(currentHash!==hash){
var action = ...;
var data = ...;
window.parent.parent[action](data);
}
},1);
存在问题:
data长度限制,在chrome,ff,safari等浏览器中hash长度限制有50K以上,但是在ie下最多2000左右的限制。
回调函数的处理
通常情况下父页面在调用子页面的方法时会有一些回调函数(函数是在parent.html中编写和执行,但是需要child.html中的方法执行完成后再执行,有些情况下会需要child.html中执行的结果)
比如(通常情况下会做接口的封装):
parent.html:
var data={.....};
childFunc.func1(data,function(result){
//result即为child.html中执行func1后的结果值
});
child.html:
var func1 = function(data,callback){
//对data的一些操作
var result = ...;
callback&&callback(result);
}
如果出现这种情况的话parent.html中定义的匿名回调函数是不可能以字符串的形式传递到child.html中去的,并且也无法在child.html中再去执行父页面的回调函数
解决方法:
在接口封装的时候将回调函数保存下来,通过一个唯一的函数名传递到child.html中,child.html中的方法执行完成后将该函数名传递到proxy.html中执行该函数
以上面的func1为例
parent.html:
var eventIndex=0;
childFunc.func1 = function(data,callback){
if(//callback是function类型){
//此时window是parent页面的对象
window["myEvent"+eventIndex] = callback;
childIframe.hash="action=...&data=...&callback=myEvent"+eventIndex;
}
};
child.html:
var currentHash = location.hash;
setInterval(function(){
var hash = location.hash.substring(1);
if(currentHash!==hash){
var action = ...;
var data = ...;
var callback=....;//应该是myEvent+index
childFuncClass[action](data,function(result){
proxyIfram.src.hash="action="+callback+"&data="+result;
});
}
},1);
proxy.html:
setInterval(function(){
if(//hash changed){
var callback = //hash.callback
var callbackData = //hash.callbackData
window.parent.parent[callback](callbackData);
}
},1);
实现方案2:window.postMessage方法
由于方案1中对ie兼容性有问题(所有ie版本,包括ie11和edge都存在这个问题),方案2使用postMessage方法,该方法理论上对数据量没有限制(猜的),并且对ie可用
同样是使用iframe嵌入,
parent.html
var iframe = document.getElementById("childFrame").contentWindow;
var msg = {data:parentData,action:childFunc,callback:/*类似于上面的方法myEventIndex*/}
var childDomain = "http://www.child.com"
iframe.postMessage(msg,childDomain);
window.addEventListener("message",function(obj){
var data = obj.data;
var action = data.action;
var data = data.data;
parentFuncClass[action](data);
});
child.html
window.addEventListener("message",function(obj){
var data = obj.data;
var action = data.action;
var data = data.data;
var callback = data.callback;
childFuncClass[action](data,function(result){
var d = {action:callback,data:result};
var parentDomain="http://www.parent.com";
window.parent.postMessage(d,parentDomain);
});
});
真的是坑啊,把方案1中的坑都走过后才找到方案2的方法
Iframe父子窗口之间的跨域事件调用和传值的更多相关文章
- 父窗口和iframe子窗口之间相互传递参数和调用函数或方法
1.父窗口向子窗口传递参数: 可以在url中添加参数:2.html?a=1&b=2&c=3 然后在子页面上可用js解析,提供一个函数: function getQueryStr(sAr ...
- JS方法在iframe父子窗口间的调用
本文向大家简单介绍一下iframe父子窗口间JS方法调用,JavaScript 被数百万计的网页用来改进设计.验证表单.检测浏览器.创建cookies,以及更多的应用,希望本文介绍对你有所帮助. if ...
- 使用document.domain和iframe实现站内AJAX跨域
站内AJAX跨域可以通过document.domain和iframe实现,比如www.css88.com.js.css88.com.css88.com这3个域名其实是3个不同的域,很多时候www.cs ...
- 使用JSONP进行跨域Ajax 调用
JSONP 是啥 JSONP 全称是JSON with Padding. 当需要进行跨域Ajax 调用的时候, 需要用到JSONP 协议. 客户端 $.ajax({ url: 'http://xxx' ...
- iframe可通过postMessage解决跨域、跨窗口消息传递
https://www.cnblogs.com/dorothyorsusie/p/6178599.html //iframe传参给父级页面 function give_info(){ console. ...
- iframe解决ajax主域和子域之间的跨域问题
在某些应用场景下,需要在主域中,调用子域中的某个接口,如果直接在主域中向子域发ajax请求,会报跨域错误,可以用iframe来解决这种跨域问题.假如主域为www.baidu.com,子域为baike. ...
- iframe父子页面之间相互调用元素和函数
<!doctype html> <html> <head> <meta http-equiv="Content-Type" content ...
- 用iframe设置代理解决ajax跨域请求问题
面对ajax跨域请求的问题,想用代理的方式来解决这个跨域问题.在服务器端创建一个静态的代理页面,在客户端用iframe调用这个代理 今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到aja ...
- 如何设置iframe高度自适应,在跨域的情况下能做到吗?
在页面上使用iframe来动态加载页面内容是网页开发中比较常见的方法.在父页面中给定一个不带滚动条的iframe,然后对属性src指定一个可加载的页面,这样当父页面被访问的时候,子页面可以被自动加载. ...
随机推荐
- 201521123091 《Java程序设计》第1周学习总结
Java 第一周总结 第一周的作业. 1.本章学习总结 [x] 初识Java语言:Java的历史,三大平台,了解JVM/JRE/JDK [x] Java开发环境的配置 [x] 用记事本编写Java程序 ...
- 201521123002《Java程序设计》第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 1.提交函数实 ...
- 201521123095 《Java程序设计》第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 Q1 List中指定元素的删除(题目4-1) 1.1 实验总结 对于删除函数 ...
- 201521123032 《Java程序设计》第7周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 ArrayList代码分析 1.1 解释ArrayList的contains源代码 在contains方法中 ...
- 201521123048 《Java程序设计》第4周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 1.多态:使用单一接口操作多种类型的对象. 2.private修饰属性,public修饰方法 ...
- 201521123085 《Java程序设计》第14周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 2. 书面作业 1. MySQL数据库基本操作 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自 ...
- 数据结构与算法->树->2-3-4树的查找,添加,删除(Java)
代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 目录 一. 2-3-4树的定义 二. 2-3-4树数据结构定义 三. 2-3-4树的可以得到 ...
- 如何实现Sublime Text3中vue文件高亮显示的最有效的方法
今天第一次使用Sublime Text3软件,在实现vue文件高亮显示的过程中一直报错,经过了半天时间的不停尝试终于找到了最有效的一种解决方法!错误提示如下: 刚开始尝试了很多方法都不行,只要打开in ...
- Python可视化----------matplotlib.pylot
1 >>> import matplotlib.pyplot as plt 2 >>> plt.axis([0,5,0,20]) 3 [0, 5, 0, 20] 4 ...
- python实例编写(7)---测试报告与测试套件(多个py文件,1个py文件内多个用例)
一. 一个.py文件批量执行测试用例(一个.py文件下多个用例执行) 如果直接使用:unittest.main(),则按字母顺序执行, 对于前后之间又依赖关系的用例,需要按特定的顺序执行,则使用 s ...