子页面iframe跨域执行父页面定义的JS方法

时间:2022-12-22 16:07:25

问题需求:父页面与子页面iframe跨域嵌套,子页面要触发父页面所定义的js方法、父子页面的数据传递。

下文中会用到一些文件:
父页面: parent.html
嵌在父页面的子iframe页面:child.html

同域时 iframe 调用父页面的JS方法

在同域的情况下,子iframe页面可以很方便地直接调用父页面定义的JS方法:
window.parent.fn(); 或者 window.top.fn();
window.self: 当前窗口自身的引用
window.parent: 上一级父窗口的引用
window.top: 最顶层窗口的引用
当页面中不存在 iframe 嵌套时,则 window.self, window.parent, window.top 三者均是当前窗口自身的引用。

比如,parent.html 和 child.html 均在 a.com 的同一域名下,

parent.html 代码:

1
2
3
4
5
6
7
8
<iframe id="gameIframe" name="gameIframe" src="./game_iframe.html"></iframe>
<!-- 或者 -->
<iframe id="gameIframe" name="gameIframe" src="a.com/game_iframe.html"></iframe>
<script>
function sayHi () {
alert('hi!');
}
</script>

child.html 代码:

1
window.parent.sayHi(); //或者 top.sayHi();

当 <iframe> 的链接与父页面不同域时,则子页面的 iframe 不能调用父页面定义的方法,会报错;
如:parent.html 在 a.com 域名下,但子 iframe 的链接与 a.com 不同域:

1
2
<iframe id="gameIframe" name="gameIframe" src="b.com/game_iframe.html"></iframe>
<!-- 此时在game_iframe.html页面调用父页面定义的方法,会报跨域错误 -->

实际上,跨域直接调用其它页面所定义的JS方法是做不到的。

postMessage 的发送与接收

Window.postMessage 是 HTML5 提供的一个跨域解决方案。基本的发送和接收使用如下:
发送:
otherWindow.postMessage(message, targetOrigin, [transfer]);
参数说明:
message: 将要发送到其他 window的数据;
otherWindow:其他窗口的一个引用,如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames;
targetOrigin: 通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串”*”(表示无限制)或者一个URI。

接收:

1
2
3
4
5
6
7
window.addEventListener("message", function(event){
var data = event.data;
// 判断域名
if(event.origin == 'http://192.168.1.237'){
//doSomething()
}
});

event 包含很多的信息,其中重要的几个分别是:
event.data :传递过来的信息,也就是 postMessage 中发出的 message;
event.origin: 发送信息页面的域名,包括协议和端口号。

跨域时 iframe 触发父页面的JS方法,数据双向传输

a.com 域名下的父页面 parent.html 定义了功能函数 sayHi();
父页面 parent.html 中嵌套了子 iframe 页面 child.html(在域名b.com域名下) ;
现在要实现:
1)在child.html中引起触发、执行父页面定义的 sayHi()方法。
2)在child.html中向父页面请求获取数据 uname 值。

基本思路:
parent.html 和 child.html 2个页面分别设置 发送和接收,如图:
子页面iframe跨域执行父页面定义的JS方法

1) child.html代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script type="text/javascript" src="sdk_child.js"></script>
<script type="text/javascript">
// 1)触发父页面定义的方法
window.SDK.sayHi({msg: 'hi'});
 
// 2)向父页面请求获取数据 uname
var uname = '';
window.SDK.getUname();
setTimeout(function(){
uname = window.SDK.uname;
//doSomething(uname);
}, 200);
// 备注:发送请求后,需要延时接收返回的数据
</script>

2) child.html 中引入的js文件 sdk_child.js 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
;(function(){
var sdk = window.SDK || {};
sdk.uname = null;
 
//发送
sdk.getUname = function(){
window.top.postMessage({
action: "getUname"
},
"*")
};
sdk.sayHi = function(info){
window.top.postMessage({
action: "sayHi",
info: {
msg: info.msg
}
},
"*")
};
//接收
window.addEventListener("message", function(e){
var res = e;
var action = res.data.action;
var info = res.data.info;
//判断域名
if(res.origin == 'a.com'){
switch (action) {
case 'getUname' :
sdk.uname = info;
break;
default :
return
}
}
});
//写入window
window.SDK = sdk;
})();

3) parent.html 中引入的js文件 sdk_parent.js代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
;(function(){
var iframecont = document.getElementById('gameIframe').contentWindow;
var sdk ={
getUname: function(){
var info = Tool.pareUrl(location.href);
iframecont.postMessage({action: 'getUname', info: 'zhangsan'}, 'b.com');
},
sayHi: function(info){
alert(info.msg);
},
};
 
//监听接收
window.addEventListener("message", function(e){
var res = e;
var data = e.data;
var info = e.data.info;
if(true){
switch (data.action) {
case 'sayHi' :
sdk.sayHi(info);
break;
case 'getUname' :
sdk.getUname();
break;
default :
return
}
}
});
})();

本文的探索,主要应用在h5游戏的JSSDK中。

子页面iframe跨域执行父页面定义的JS方法的更多相关文章

  1. iframe 跨域调用父级方法的方案

    一.如果高层域名相同的话,可以通过document.domain来实现跨域访问 例如: 父级域名:localhost:8080 子级域名:localhost:9090 那么可以设置document.d ...

  2. iFrame跨域的方式

    4种通过iframe跨域与其他页面通信的方式 不同域下的iframe不能进行操作. 1.location.hash: 在url中,http://www.baidu.com#helloword的#hel ...

  3. iframe子页面点击按钮,执行父页面的点击事件

    iframe 子页面点击.parent 父页面  的id(auth-link-btn)的事件 <a href="javascript:void(0);" onclick=&q ...

  4. 解决Iframe跨域高度自适应&comma;利用window&period;postMessage&lpar;&rpar;实现跨域消息传递页面高度(JavaScript)

    在iframe跨域引用高度自适应这块写的js方式都试了不管用,最终使用的是window.postMessage() 跨域获取高度 传递信息 1.首先,在主页面上使用iframe引入子页面:也就是A.h ...

  5. chrome浏览器下用jQuery的load函数来跨域加载页面,响应状态status为&lpar;canceled&rpar;是什么情况? JSON和JSONP,也许你会豁然开朗,含jQuery用例

    http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html 问题来源:http://q.cnblogs.com ...

  6. iphone在iframe页面的宽度不受父页面影响,避免撑开页面

    工作中有个需求,就是产品页面通过iframe引用显示产品协议页,要求不要横向滑动,只需要竖向滑动,但在iphone中引用的iframe会撑开父页的宽度,而在android端浏览器这不会. <di ...

  7. js 两个页面的传值 可以用父页面 子页面做

    js  两个页面的传值  可以用父页面 子页面做 比如弹窗  将值传到子页面的时候  用get超长

  8. JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  9. 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

随机推荐

  1. &period;md文件的语法

    md全称是Macdown,.md文件可以当记事本一样使用,作为编辑软件,还可以自己添加样式,图片,链接等,可以用记事本打开,也可以保持样式排版转换为html文件,语法比较简单..md除了编辑容易的优势 ...

  2. 安卓问题集-Installation error&colon; INSTALL&lowbar;PARSE&lowbar;FAILED&lowbar;MANIFEST&lowbar;MALFORMED

    错误出现原因: 1.没有 AndroidManifest.xml file文件(出现几率较小) 2. 是你在外面修改了包名而在 AndroidManifest.xml file.文件中没有同步过去导致 ...

  3. Scala:使用Sublime开发Scala

    Scala:使用Sublime开发Scala 第一步:[Tools][Build System][New Build System] 第二步:在打开的新文件中输入: { //"cmd&quo ...

  4. Android 4&period;4KitKat AudioRecord 流程分析

    Android是架构分为三层: 底层      Linux Kernel 中间层  主要由C++实现 (Android 60%源码都是C++实现) 应用层  主要由JAVA开发的应用程序 应用程序执行 ...

  5. PHP设计模式之装饰器模式

    装饰器模式:如果已有对象的部分内容或功能性发生改变,但是不需要修改原始对象的结构或不使用继承,动态的扩展一个对象的功能,则应该使用装饰器模式.简单点说:就是我们不应该去修改已有的类,而是通过创建另外一 ...

  6. js的框架

    Ember.js的一些学习总结   1.1.1 摘要 现在,我们经常都可以看到复杂的JavaScript应用程序,由于这些应用程序变得越来越复杂,一长串的jQuery回调语句或者通过应用程序在各个状态 ...

  7. xxx&period;java&colon; Recompile with -Xlint&colon;deprecation for details

    警告而已.有些方法1 已经过时,有更好的方法可以代替,比如 new java.util.Date().getYear(); => cal.get(Calendar.YEAR);2 发现过问题,且 ...

  8. 展示博客(Beta阶段)

    展示博客 0x00 团队成员 成员 博客地址 简介 黄建英 http://www.cnblogs.com/smilehjy/ beta阶段的新成员,负责前端界面调整 谢晓萍 http://www.cn ...

  9. spring mvc 在上传图片时,浏览器报The request sent by the client was syntactically incorrect

    项目中,在一个jsp页面里其它图片上传是功能是可以使用的,当我自己新加了一个图片上传时,提交表单后,浏览器报The request sent by the client was syntactical ...

  10. jinja2

    本文转自:https://www.cnblogs.com/dachenzi/p/8242713.html 模板 要了解jinja2,那么需要先理解模板的概念.模板在Python的web开发中广泛使用, ...