苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 5522|回复: 4

[HTML/HTML5] Iframe父子窗口之间的跨域事件调用和传值

[复制链接]
发表于 2017-10-18 21:07:37 | 显示全部楼层 |阅读模式
Iframe父子窗口之间的跨域事件调用和传值

实现方案1:location.hash传值
父页面:parent.html(所在域:www.parent.com

子页面:child.html(所在域:www.child.com

要实现父子页面双向的事件调用和传值,需要多加一个代理页面,主要用于子页面调用父页面的方法

代理页面:proxy.html(所在域:www.parent.com)必须与父页面在同域下



父页面调用子页面方法(即事件通过父页面发起,在子页面中执行):
父页面中直接设置iframe的src中的hash值

parent.html:
[C#] 纯文本查看 复制代码
var frameurl = "http://www.child.com/child.html"

document.getElementById("frameId").src=frameurl+"#action="+actionName+"&data="+dataJSONStr;

子页面中设置定时器监听hash的变化,监听到后直接执行该方法

child.html:
[C#] 纯文本查看 复制代码
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:
[C#] 纯文本查看 复制代码
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:
[C#] 纯文本查看 复制代码
var data={.....};


childFunc.func1(data,function(result){

//result即为child.html中执行func1后的结果值

});

child.html:
[C#] 纯文本查看 复制代码
var func1 = function(data,callback){

//对data的一些操作

var result = ...;

callback&&callback(result);

}

如果出现这种情况的话parent.html中定义的匿名回调函数是不可能以字符串的形式传递到child.html中去的,并且也无法在child.html中再去执行父页面的回调函数



1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
 楼主| 发表于 2017-10-18 21:07:59 | 显示全部楼层

解决方法:

在接口封装的时候将回调函数保存下来,通过一个唯一的函数名传递到child.html中,child.html中的方法执行完成后将该函数名传递到proxy.html中执行该函数

以上面的func1为例

parent.html:

[C#] 纯文本查看 复制代码
var eventIndex=0;
childFunc.func1 = function(data,callback){
if(//callback是function类型){
//此时window是parent页面的对象
window["myEvent"+eventIndex] = callback;<br>
childIframe.hash="action=...&data=...&callback=myEvent"+eventIndex;<br>
}
};


child.html:
[C#] 纯文本查看 复制代码
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:
[C#] 纯文本查看 复制代码
setInterval(function(){

  if(//hash changed){

    var callback = //hash.callback
    var callbackData = //hash.callbackData
    window.parent.parent[callback](callbackData);
  }

},1);
 楼主| 发表于 2017-10-18 21:10:25 | 显示全部楼层


实现方案2:window.postMessage方法
由于方案1中对ie兼容性有问题(所有ie版本,包括ie11和edge都存在这个问题),方案2使用postMessage方法,该方法理论上对数据量没有限制(猜的),并且对ie可用

同样是使用iframe嵌入,

parent.html
[C#] 纯文本查看 复制代码
var iframe = document.getElementById("childFrame").contentWindow;

var msg = {data:parentData,action:childFunc,callback:/*类似于上面的方法myEventIndex*/}
var childDomain = "http://www.SUFEINET.COM"
iframe.postMessage(msg,childDomain);

[C#] 纯文本查看 复制代码
window.addEventListener("message",function(obj){
var data = obj.data;
var action = data.action;
var data = data.data;
parentFuncClass[action](data);
});
1
<br>

child.html
[C#] 纯文本查看 复制代码
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.SUFEINET.COM";
window.parent.postMessage(d,parentDomain);
});
});

真的是坑啊,把方案1中的坑都走过后才找到方案2的方法
 楼主| 发表于 2017-10-18 21:11:51 | 显示全部楼层
发表于 2017-10-19 11:47:09 | 显示全部楼层
实用的方法
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-12-24 03:38

© 2014-2021

快速回复 返回顶部 返回列表