跨域 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),核心是确保不同源提供的文件之间是相互独立的 默认情况下 ...
随机推荐
- Android Bitmap 载入与像素操作
Android Bitmap 载入与像素操作 一:载入与像素读写 在Android SDK中,图像的像素读写能够通过getPixel与setPixel两个Bitmap的API实现. Bitmap AP ...
- 測试JSON RPC远程调用(JSONclient)
#include <string> #include <iostream> #include <curl/curl.h> /* 标题:JSonclient Auth ...
- java 字符串 asc 加密解密
package com; public class MD5Test { /** * @param args */ public static void main(String[] args) { Sy ...
- Linux中块设备驱动程序分析
基于<Linux设备驱动程序>书中的sbull程序以对Linux块设备驱动总结分析. 開始之前先来了解这个块设备中的核心数据结构: struct sbull_dev { i ...
- Javascript语言精粹之正则表达式知识整理
Javascript语言精粹之正则表达式知识整理 1.正则表达式思维导图 2.正则表达式常用示例 2.1 移除所有标签,只留下innerText var html = "<p>& ...
- Date()创建日期
哎. .这些人变得懒惰个月...经过以上撰写博客的工作 上周五测试报告的问题.上述日期的计算是有问题.两个日期之间的差异原创1天,然而,系统将计算的差31天. (就在那一天2014年10月31日本 星 ...
- Cocos2d-x 地图步行实现1:图论Dijkstra算法
下一节<Cocos2d-x 地图行走的实现2:SPFA算法>: http://blog.csdn.net/stevenkylelee/article/details/38440663 本文 ...
- Android实现限制EditText输入文字的数量
一: 声明控件. TextView hasnumTV; TextView hasnum;// 用来显示剩余字数 int num = 50;// 限制的 ...
- IAR FOR ARM 各版本号,须要的大家能够收藏了
首先感谢大家的支持与关注,如今应该又一次编辑这篇文章了,这篇文章是非常久曾经不知在什么地方Copy过来的, 非常多问题不知怎么解决,如今我用的是KEIL for arm. 用过Keil和IAR,个人感 ...
- [WebView五学习]:调试Web Apps
上一篇我们学习了([WebView学习之四]:迁移到Android4.4版本号的WebView),今天我们来继续学习. (博客地址:http://blog.csdn.net/developer_jia ...