跨域 Iframe 通信解决方案(兼容 IE 系列浏览器。)
实现思路:
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 系列浏览器。)的更多相关文章
- 跨域iframe高度自适应(兼容IE/FF/OP/Chrome)
		采用JavaScript来控制iframe元素的高度是iframe高度自适应的关键,同时由于JavaScript对不同域名下权限的控制,引发出同域.跨域两种情况. 由于客户端js使用浏览器的同源安全策 ... 
- 完美实现跨域Iframe高度自适应【Iframe跨域高度自适应解决方案】
		Iframe的强大功能偶就不多说了,它不但被开发人员经常运用,而且黑客们也常常使用它,总之用过的人知道它的强大之处,但是Iframe有个致命的“BUG”就是iframe的高度无法自动适应,这一点让很多 ... 
- javascript跨域通信(一):利用location.hash实现跨域iframe自适应
		页面域关系: a.html所属域A:www.A.comb.html所属域B:www.B.com 问题本质: js对跨域iframe访问问题,因为要控制a.html中iframe的高度和宽度就必须首先读 ... 
- 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 ... 
- ajax跨域原理以及解决方案
		说明 跨域主要是由于浏览器的“同源策略”引起,分为多种类型,本文主要探讨Ajax请求跨域问题 前言 强烈推荐阅读参考来源中的文章,能够快速帮助了解跨域的原理 参考来源 本文参考了以下来源 浏览器同源政 ... 
- 跨域问题,解决方案-Nginx反向代理
		跨域问题,解决之道 跨域问题,在日常开发过程中,是一个非常熟悉的名词.今天的话题,结合我之前的项目场景,讨论下<跨域问题,解决之道>. 跨域是什么 跨域问题,是由于JavaScript出于 ... 
- 谷歌、火狐浏览器下实现JS跨域iframe高度自适应的完美解决方法,跨域调用JS不再是难题!
		谷歌.火狐浏览器下实现JS跨域iframe高度自适应的解决方法 导读:今天开发的时候遇到个iframe自适应高度的问题,相信大家对这个不陌生,但是一般我们都是在同一个项目使用iframe嵌套页面,这个 ... 
- ajax 跨域访问的解决方案
		ajax 跨域访问的解决方案 一.什么是跨域: 1.什么样的请求属于跨域: 域名,端口有任何一个不相同都属于跨域: 二.跨域的常用几种解决方案: 1.jsonp: 2.iframe: 3.webcon ... 
- Web学习之跨域问题及解决方案
		在做前端开发时,我们时常使用ajax与服务器通信获取资源,享受ajax便利的同时,也知道它有限制:跨域安全限制,即同源策略. 同源策略(SOP),核心是确保不同源提供的文件之间是相互独立的 默认情况下 ... 
随机推荐
- Windows phone 8 学习笔记(2) 数据文件操作
			原文:Windows phone 8 学习笔记(2) 数据文件操作 Windows phone 8 应用用于数据文件存储访问的位置仅仅限于安装文件夹.本地文件夹(独立存储空间).媒体库和SD卡四个地方 ... 
- Hive综合HBase——经Hive阅读/书写 HBase桌子
			社论: 本文将Hive与HBase整合在一起,使Hive能够读取HBase中的数据,让Hadoop生态系统中最为经常使用的两大框架互相结合.相得益彰. watermark/2/text/aHR0cDo ... 
- easyui出口excel无法下载框弹出的办法来解决
			使用前ajax发,码如下面(ActionUrl一般处理程序ashx路径): $.ajax({ url: ActionUrl + '?action=export&ID=' + $('#fm_ID ... 
- [状压dp] hdu 4064 Carcassonne
			题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4064 Carcassonne Time Limit: 3000/1000 MS (Java/Othe ... 
- Google的Guava它Collection升华
			至于Guava这是不是在这里说.一个已被提上一个非常特殊的! 这主要是为了分享Guava对于一些升华处理组.井,不多说了,直接在代码: package com.joyce.guava.bean; /* ... 
- JQuery操作select checkbox radio总结
			JQuery是一个非常强大的工具,所以我必须找到它最方便的方法,嘻嘻 Select CRUD: Select搜: 1.val值: $("#selectid").val(); ... 
- android学习经常使用的数据文件夹
			android工程实践 1.仿360一键清理实现(一) "一键清理"是一个桌面图标,点击图标后,显示一个视图.进行清理动画.之后显示清理了几个进程,释放了多少M内存.点击" ... 
- 自动同步Android源代码的脚本(repo sync)
			#!/bin/bash echo "================start repo sync====================" repo sync -j5 ]; do ... 
- Java Swing 树状组件JTree的使用方法(转)
			树中特定的节点可以由 TreePath(封装节点及其所有祖先的对象)标识,或由其显示行(其中显示区域中的每一行都显示一个节点)标识.展开 节点是一个非叶节点(由返回 false 的 TreeModel ... 
- React Native是一套使用 React 构建 Native app 的编程框架
			React Native是一套使用 React 构建 Native app 的编程框架 React Native at first sight what is React Native? 跟据官方的描 ... 
