实现思路:

1、postMessage(IE8+, Firefox 3.1+, Opera 9+, Safari, and Chrome)

2、利用window.navigator共享信息,使支持IE6,IE7

i、父窗口向子窗口iframe发送信息:

               document.getElementById("childiframe").contentWindow .postMessage(
"我是父窗口",
"http://child.com:8080" //可以*通配符代替,表示支持所有域
);

上面的代码表示父窗口向子iframe:childiframe,域名为"http://child.com:8080"  发送 "我是父窗口"的消息

ii、子iframe

               window.addEventListener("message", function( event ) {
// 把父窗口发送过来的数据显示在子窗口中
document.getElementById("content").innerHTML+=event.data+"<br/>";
}, false );

iii、父窗口如果有多个子iframe,那么父窗口可以向多个子窗口发送消息

利用Object-orient-programing  ,父窗口和多个子窗口分别实例化一个Message对象,各个窗口的message对象里开辟一个内存可以保存多个目标对象Target,意思是要发送消息到这些目标,

Target对象实现自己的send方法 ,send考虑到浏览器的兼容性,Target对象里保存了target和name信息,target表示要发送的窗口,name是发送目标的名称 ,name的作用仅仅是支持IE6、7中使用到(在window.navigator标示一个唯一send的回调函数)

     var prefix = "arale-messenger",
        supportPostMessage = 'postMessage' in window;
// Target 类, 消息对象
function Target(target, name){
var errMsg = '';
if(arguments.length < 2){
errMsg = 'target error - target and name are both required';
} else if (typeof target != 'object'){
errMsg = 'target error - target itself must be window object';
} else if (typeof name != 'string'){
errMsg = 'target error - target name must be string type';
}
if(errMsg){
throw new Error(errMsg);
}
this.target = target;
this.name = name;
} // 往 target 发送消息, 出于安全考虑, 发送消息会带上前缀
if ( supportPostMessage ){
// IE8+ 以及现代浏览器支持
Target.prototype.send = function(msg){
this.target.postMessage(prefix + msg, '*');
};
} else {
// 兼容IE 6/7 利用window.navigator共享信息,使支持IE6,IE7
Target.prototype.send = function(msg){
var targetFunc = window.navigator[prefix + this.name];
if ( typeof targetFunc == 'function' ) {
targetFunc(prefix + msg, window);
} else {
throw new Error("target callback function is not defined");
}
};
}

iiii: 每个窗口都实例化的Message类:

targets 里保存目标发送对象,name当前窗口的名字,最后会传给Target,也是只在兼容IE6、7中用到。

listenFunc :保存监听的回调,一个页面可以实现多个监听。

initListen :ie6、7中保存全局回调函数,以方便在Target的send中触发

IE8+和现代化浏览器中监听message事件。

    // 信使类
// 创建Messenger实例时指定, 必须指定Messenger的名字, (可选)指定项目名, 以避免Mashup类应用中的冲突
// !注意: 父子页面中projectName必须保持一致, 否则无法匹配
function Messenger(messengerName, projectName){
this.targets = {};
this.name = messengerName;
this.listenFunc = [];
prefix = projectName || prefix;
this.initListen();
} // 添加一个消息对象
Messenger.prototype.addTarget = function(target, name){
var targetObj = new Target(target, name);
this.targets[name] = targetObj;
}; // 初始化消息监听
Messenger.prototype.initListen = function(){
var self = this;
var generalCallback = function(msg){
if(typeof msg == 'object' && msg.data){
msg = msg.data;
}
// 剥离消息前缀
msg = msg.slice(prefix.length);
for(var i = 0; i < self.listenFunc.length; i++){
self.listenFunc[i](msg);
}
}; if ( supportPostMessage ){
if ( 'addEventListener' in document ) {
window.addEventListener('message', generalCallback, false);
} else if ( 'attachEvent' in document ) {
window.attachEvent('onmessage', generalCallback);
}
} else {
// 兼容IE 6/7
window.navigator[prefix + this.name] = generalCallback;
}
}; // 监听消息
Messenger.prototype.listen = function(callback){
this.listenFunc.push(callback);
};
// 注销监听
Messenger.prototype.clear = function(){
this.listenFunc = [];
};
// 广播消息
Messenger.prototype.send = function(msg){
var targets = this.targets,
target;
for(target in targets){
if(targets.hasOwnProperty(target)){
targets[target].send(msg);
}
}
};

完整demo:

完整代码:

message.js

(function(w){
// 消息前缀, 建议使用自己的项目名, 避免多项目之间的冲突
var prefix = "arale-messenger",
supportPostMessage = 'postMessage' in window; // Target 类, 消息对象
function Target(target, name){
var errMsg = '';
if(arguments.length < 2){
errMsg = 'target error - target and name are both required';
} else if (typeof target != 'object'){
errMsg = 'target error - target itself must be window object';
} else if (typeof name != 'string'){
errMsg = 'target error - target name must be string type';
}
if(errMsg){
throw new Error(errMsg);
}
this.target = target;
this.name = name;
} // 往 target 发送消息, 出于安全考虑, 发送消息会带上前缀
if ( supportPostMessage ){
// IE8+ 以及现代浏览器支持
Target.prototype.send = function(msg){
this.target.postMessage(prefix + msg, '*');
};
} else {
// 兼容IE 6/7
Target.prototype.send = function(msg){
var targetFunc = window.navigator[prefix + this.name];
if ( typeof targetFunc == 'function' ) {
targetFunc(prefix + msg, window);
} else {
throw new Error("target callback function is not defined");
}
};
} // 信使类
// 创建Messenger实例时指定, 必须指定Messenger的名字, (可选)指定项目名, 以避免Mashup类应用中的冲突
// !注意: 父子页面中projectName必须保持一致, 否则无法匹配
function Messenger(messengerName, projectName){
this.targets = {};
this.name = messengerName;
this.listenFunc = [];
prefix = projectName || prefix;
this.initListen();
} // 添加一个消息对象
Messenger.prototype.addTarget = function(target, name){
var targetObj = new Target(target, name);
this.targets[name] = targetObj;
}; // 初始化消息监听
Messenger.prototype.initListen = function(){
var self = this;
var generalCallback = function(msg){
if(typeof msg == 'object' && msg.data){
msg = msg.data;
}
// 剥离消息前缀
msg = msg.slice(prefix.length);
for(var i = 0; i < self.listenFunc.length; i++){
self.listenFunc[i](msg);
}
}; if ( supportPostMessage ){
if ( 'addEventListener' in document ) {
window.addEventListener('message', generalCallback, false);
} else if ( 'attachEvent' in document ) {
window.attachEvent('onmessage', generalCallback);
}
} else {
// 兼容IE 6/7
window.navigator[prefix + this.name] = generalCallback;
}
}; // 监听消息
Messenger.prototype.listen = function(callback){
this.listenFunc.push(callback);
};
// 注销监听
Messenger.prototype.clear = function(){
this.listenFunc = [];
};
// 广播消息
Messenger.prototype.send = function(msg){
var targets = this.targets,
target;
for(target in targets){
if(targets.hasOwnProperty(target)){
targets[target].send(msg);
}
}
}; w["Messenger"]=Messenger;
})(window);

child.html:

<!doctype html>
<html>
<head>
<script type="text/javascript" src="message.js"></script>
<script>
window.onload=function(){
var messenger = new Messenger('iframe1', 'MessengerProject');
messenger.addTarget(window.parent, 'parent');
messenger.targets['parent'].send('发给父页面的消息');
messenger.listen(function(msg) {
document.getElementById("msg").innerHTML=msg;
});
}
</script>
</head>
<body>
child
<div id="msg"></div>
</body>
</html>

parent.html

<!doctype html>
<html>
<head>
<script type="text/javascript" src="message.js"></script>
<script>
window.onload=function(){
var messenger = new Messenger('parent', 'MessengerProject');
var iframe1=window.iframe1;
messenger.addTarget(iframe1.contentWindow, 'iframe1');
messenger.targets['iframe1'].send('发给子页面1的消息');
messenger.listen(function(msg) {
document.getElementById("msg").innerHTML=msg;
});
}
</script>
</head>
<body>
parent
<div id="msg"></div>
<iframe id="iframe1" src="child.html" width=100 height=100>
</body>
</html>

跨域 Iframe 通信解决方案(兼容 IE 系列浏览器。)的更多相关文章

  1. 跨域iframe高度自适应(兼容IE/FF/OP/Chrome)

    采用JavaScript来控制iframe元素的高度是iframe高度自适应的关键,同时由于JavaScript对不同域名下权限的控制,引发出同域.跨域两种情况. 由于客户端js使用浏览器的同源安全策 ...

  2. 完美实现跨域Iframe高度自适应【Iframe跨域高度自适应解决方案】

    Iframe的强大功能偶就不多说了,它不但被开发人员经常运用,而且黑客们也常常使用它,总之用过的人知道它的强大之处,但是Iframe有个致命的“BUG”就是iframe的高度无法自动适应,这一点让很多 ...

  3. javascript跨域通信(一):利用location.hash实现跨域iframe自适应

    页面域关系: a.html所属域A:www.A.comb.html所属域B:www.B.com 问题本质: js对跨域iframe访问问题,因为要控制a.html中iframe的高度和宽度就必须首先读 ...

  4. Ajax跨域问题及解决方案 asp.net core 系列之允许跨越访问(Enable Cross-Origin Requests:CORS) c#中的Cache缓存技术 C#中的Cookie C#串口扫描枪的简单实现 c#Socket服务器与客户端的开发(2)

    Ajax跨域问题及解决方案   目录 复现Ajax跨域问题 Ajax跨域介绍 Ajax跨域解决方案 一. 在服务端添加响应头Access-Control-Allow-Origin 二. 使用JSONP ...

  5. ajax跨域原理以及解决方案

    说明 跨域主要是由于浏览器的“同源策略”引起,分为多种类型,本文主要探讨Ajax请求跨域问题 前言 强烈推荐阅读参考来源中的文章,能够快速帮助了解跨域的原理 参考来源 本文参考了以下来源 浏览器同源政 ...

  6. 跨域问题,解决方案-Nginx反向代理

    跨域问题,解决之道 跨域问题,在日常开发过程中,是一个非常熟悉的名词.今天的话题,结合我之前的项目场景,讨论下<跨域问题,解决之道>. 跨域是什么 跨域问题,是由于JavaScript出于 ...

  7. 谷歌、火狐浏览器下实现JS跨域iframe高度自适应的完美解决方法,跨域调用JS不再是难题!

    谷歌.火狐浏览器下实现JS跨域iframe高度自适应的解决方法 导读:今天开发的时候遇到个iframe自适应高度的问题,相信大家对这个不陌生,但是一般我们都是在同一个项目使用iframe嵌套页面,这个 ...

  8. ajax 跨域访问的解决方案

    ajax 跨域访问的解决方案 一.什么是跨域: 1.什么样的请求属于跨域: 域名,端口有任何一个不相同都属于跨域: 二.跨域的常用几种解决方案: 1.jsonp: 2.iframe: 3.webcon ...

  9. Web学习之跨域问题及解决方案

    在做前端开发时,我们时常使用ajax与服务器通信获取资源,享受ajax便利的同时,也知道它有限制:跨域安全限制,即同源策略. 同源策略(SOP),核心是确保不同源提供的文件之间是相互独立的 默认情况下 ...

随机推荐

  1. Java文件压缩分割(待)

    http://blog.csdn.net/ycg01/article/details/1366648

  2. bootstrap jQuery Ztree异步载入数据,check选择&amp;可加入、改动、删除节点

    效果图: 一.下载zTree插件 地址:http://www.ztree.me 二.html代码 <link href="../Scripts/zTree/css/zTreeStyle ...

  3. HDU 1253-大逃亡(裸-DBFS)

    G - 胜利大逃亡 Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit St ...

  4. JavaScript的作用域和变量对象

    变量对象 先来说说什么是变量对象.变量对象中又存储了什么东西吧. JavaScript中的运行环境包含全局运行环境和函数运行环境这两种,每进入到一个运行环境都会创建一个变量对象,这个对象中记录了在当前 ...

  5. Bootstrap网站模板

    根据一篇文章,我再想想写下,无意义,他决定收手. 或者直接做一个简单的基本的模板它 主要知识点包含栅格系统.响应式图片.导航条(固定在顶部和底部).搜索框等等 详细每一个知识点不再赘述,參考Boots ...

  6. Error: ORA-16501: the Data Guard broker operation failed ORA-16625: cannot reach database

    在备库上建配置文件 DGMGRL> create configuration 'sharkdbbork' as primary database is 'sharkdb' connect ide ...

  7. Java对于私有变量“反思暴力”技术

    (1)这两个类:(在相同的包装可以是) watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font/5a6L5L2T/font ...

  8. Codeforces Round #248 (Div. 1)——Nanami&#39;s Digital Board

    题目连接 题意: 给n*m的0/1矩阵,q次操作,每次有两种:1)将x,y位置值翻转 2)计算以(x,y)为边界的矩形的面积最大值 (1 ≤ n, m, q ≤ 1000) 分析: 考虑以(x,y)为 ...

  9. 重新想象 Windows 8 Store Apps (10) - 控件之 ScrollViewer 特性: Chaining, Rail, Inertia, Snap, Zoom

    原文:重新想象 Windows 8 Store Apps (10) - 控件之 ScrollViewer 特性: Chaining, Rail, Inertia, Snap, Zoom [源码下载] ...

  10. ps命令用法详解(转)

    ps p 22763  -L -o pcpu,pid,tid,time,tname,cmd,pmem,rss --sort rss  按rss排序 ps p 26653 -L -o pcpu,tid ...