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指定一个可加载的页面,这样当父页面被访问的时候,子页面可以被自动加载. ...
随机推荐
- 201521123023《Java程序设计》第7周学习总结
1. 本周学习总结 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 分析:该方法实现了ArrayList数组的遍历,从而确定所查内容是否存在 1 ...
- 201521123080《Java程序设计》第6周学习总结
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...
- 戴建钊 201521123023《Java程序设计》第1周学习总结
1. 本周学习总结 Java 不同于C语言面向过程的编程思想,它是一种面向对象的编程方式,其在语句语法上与C++类似,因此刚开始可能比较容易理解 2. 书面作业 为什么java程序可以跨平台运行?执行 ...
- 201521123002 《Java程序设计》第1周学习总结
1. 本章学习总结 学习使用Markdown编写文章 jdk的安装和环境变量的设置 java的历史,目前java有三大平台,javaSE,javaEE及javaME.其中javaSE我们会经常用到,由 ...
- 201521123026《Java程序设》 第10周学习总结
1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 1.守护线程:setDaemon(true or false),如果所有前台线程死亡,守护线程自动结束,一般 ...
- YYHS-Floor it
题目描述 输入 输出 样例输入 5 97 样例输出 11 提示 题解 先不管p,通过列举前面几项,不难发现当i为偶数时,a[i]=a[i-1]+a[i-2],当i为奇数时,a[i]=a[i ...
- Spring第二篇和第三篇的补充【JavaConfig配置、c名称空间、装载集合、JavaConfig与XML组合】
前言 在写完Spring第二和第三篇后,去读了Spring In Action这本书-发现有知识点要补充,知识点跨越了第二和第三篇,因此专门再开一篇博文来写- 通过java代码配置bean 由于Spr ...
- Hibernate4+EhCache配置二级缓存
本文主要讲一讲Hibernate+EhCache配置二级缓存的基本使用方法 (有关EhCache的基础介绍可参见:http://sjsky.iteye.com/blog/1288257 ) Cache ...
- python 集合的操作
list_1 = set([1,2,3,4,5])#print(list_1,type(list_1))list_2 = set([1,2,3,6,7,8,9,10])#print(list_2,ty ...
- [python学习笔记] pyqt5下载与安装
下载 命令安装 pip3 install PyQt5 但是我这里老安装失败 失败问题 host='pypi.python.org', port=443): Read timed out 方案1:加大命 ...