实现方案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父子窗口之间的跨域事件调用和传值的更多相关文章

  1. 父窗口和iframe子窗口之间相互传递参数和调用函数或方法

    1.父窗口向子窗口传递参数: 可以在url中添加参数:2.html?a=1&b=2&c=3 然后在子页面上可用js解析,提供一个函数: function getQueryStr(sAr ...

  2. JS方法在iframe父子窗口间的调用

    本文向大家简单介绍一下iframe父子窗口间JS方法调用,JavaScript 被数百万计的网页用来改进设计.验证表单.检测浏览器.创建cookies,以及更多的应用,希望本文介绍对你有所帮助. if ...

  3. 使用document.domain和iframe实现站内AJAX跨域

    站内AJAX跨域可以通过document.domain和iframe实现,比如www.css88.com.js.css88.com.css88.com这3个域名其实是3个不同的域,很多时候www.cs ...

  4. 使用JSONP进行跨域Ajax 调用

    JSONP 是啥 JSONP 全称是JSON with Padding. 当需要进行跨域Ajax 调用的时候, 需要用到JSONP 协议. 客户端 $.ajax({ url: 'http://xxx' ...

  5. iframe可通过postMessage解决跨域、跨窗口消息传递

    https://www.cnblogs.com/dorothyorsusie/p/6178599.html //iframe传参给父级页面 function give_info(){ console. ...

  6. iframe解决ajax主域和子域之间的跨域问题

    在某些应用场景下,需要在主域中,调用子域中的某个接口,如果直接在主域中向子域发ajax请求,会报跨域错误,可以用iframe来解决这种跨域问题.假如主域为www.baidu.com,子域为baike. ...

  7. iframe父子页面之间相互调用元素和函数

    <!doctype html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. 用iframe设置代理解决ajax跨域请求问题

    面对ajax跨域请求的问题,想用代理的方式来解决这个跨域问题.在服务器端创建一个静态的代理页面,在客户端用iframe调用这个代理 今天在项目中需要做远程数据加载并渲染页面,直到开发阶段才意识到aja ...

  9. 如何设置iframe高度自适应,在跨域的情况下能做到吗?

    在页面上使用iframe来动态加载页面内容是网页开发中比较常见的方法.在父页面中给定一个不带滚动条的iframe,然后对属性src指定一个可加载的页面,这样当父页面被访问的时候,子页面可以被自动加载. ...

随机推荐

  1. 1st_homework_SE--四则运算题目生成器

    0x00 Code 查询源代码及README请点此 0x01 需求分析 实现一个自动生成小学四则运算题目的命令行程序. 0x02 功能设计 主要功能为: 接受用户输入以便知道要出多少道题目python ...

  2. 201521123095 《Java程序设计》第5周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.1 com.parent包中Child.java文件能否编译通过?哪句会出现错误?试改正该错误.并分析输出 ...

  3. 201521123026 《JAVA程序设计》第12周学习总结

    1. 本周学习总结 Q1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 Q1.将Student对象(属性:int id, String name,int age,d ...

  4. 三分钟深入TT猫之故障转移

    结束了一周繁忙的工作,趁着周末,小编手中的键盘早已饥渴难耐了,想知道上期省略号中发生了什么有趣的故事么?且听小编娓娓道来,结尾有彩蛋. 目录 风月前场 梦回现实 模拟老鸨 会话机制 故障转移 总结 风 ...

  5. weblogic服务器上类或者方法找不到的解决办法

    下面以eclipse-birt(报表)为例,介绍这种问题出现的原因以及解决之道: 分析比较好的见:http://developer.actuate.com/community/forum/index. ...

  6. Spring @RequestParam乱码问题

    在网上找了很多资料才找到解决的方法,通过URL传递命名参数,后台接收的却是乱码解决方法如下: 方法一:将接收的参数重新编码 @RequestMapping(value="/handle&qu ...

  7. [android游戏开发初学]SurfaceView初探之缓冲区测试

    先上测试代码 private static class PathView extends SurfaceView implements SurfaceHolder.Callback{ private ...

  8. xgboost安装指南(win10,win7 64位)

    ---恢复内容开始--- Win7 64位系统下安装XGBoost 1. 环境介绍 计算机系统:win7 64位 Xgboost版本:xgboost0.6 2. 依赖软件环境 1) python 64 ...

  9. Minutes和TotalMinutes的区别

    今天测试提了一个BUG,说是消息提醒的时机不对,设置的提前2小时,还没到就提醒了. 看了下代码 (m.ExpectReceiveTime - DateTime.Now).Minutes < (p ...

  10. Java虚拟机-运行时数据区域

    Java虚拟机管理的内存包括如图所示的运行时数据区域: 下面分别进行介绍: 1)程序计数器(Program Counter Register) 占用的内存空间比较小,主要作用就是标识当前线程执行的字节 ...