跨域传值即主页面与iframe之间互相传值

需求一:主页面A 怎么向 iframe B 传递数据呢?

这种方式,是主页面需要给 iframe B 传递数据,然后 iframe B 获得到数据后进行特定的处理

实现方式

实现的技巧就是利用 location 对象的 hash 值,通过它传递通信数据,我们只需要在主页面A中设置 iframe B 的 src 后面多加个 #data 字符串(data就是你要传递的数据),如下图所示:

然后在 iframe B 中通过某种方式能即时的获取到这儿 data 就可以了,其实常用的一种方式就是:

1. 在 iframe B 中通过 setInterval 方法设置定时器, 监听 location.href 的变化即可获得上面的 data 信息
2. 然后 iframe B 就能根据这个 data 信息进行相应的逻辑处理

需求二:iframe B 怎么向 主页面A 传递数据呢?

这种方式,是 iframe B 需要给主页面传递数据,然后主页面根据获得到数据后进行特定的处理

实现方式

实现的技巧就是利用一个代理 IframeC,它嵌入到 iframe B 中,并且和主页面A必须保持是同域,然后我们通过它充分利用上面第一种通信方式的实现原理就能把 iframe B 的数据传递给 iframeC,接下来的问题就是怎么让iframeC把数据传递给主页面A ,如下图所示:

因为,iframeC 和主页面是同域的,所以它们之间传递数据就变得简单多了,我们这里的方式就是使用一个经常使用的属性 window.top (也可以使用window.parent.parent),它返回对载入浏览器得最顶层 window 对象的引用,这样我们就能直接条用主页面A中方法啦,哈哈哈,简单吧。
到此,我们做个简单分析总结

这种实现方式的前提也是最大的缺点就是 iframe 中的内容必须是我们可控的,但是至少我们这种实现方式是建立在浏览器的安全规则之上的,没有破坏应用本身的安全性。
实现时需要考虑的一些细节

尽量考虑到了易用,可扩展性和可维护性,比如:

让第三方 App 只需加载一个我们提供的JS种子文件就能很方便的使用我们为其提供的各种工具
上面的各种工具,我们采用包的形式进行组织,最大化的实现按需加载
第一条中的JS种子文件只提供基础的方法实现,并且把最常用的工具包放在里面,比如高度自适应
通过种子文件,我们还提供给第三方 App 一些常用的JS工具包,而且直接使用的类似YUI3模块的动态加载机制就可使用指定的工具包
对第三方 App 和 主页面传递的数据进行分类(自我调用,登录验证,传递数据等等)
传递的数据使用满足特定规范的JSON格式,并通过统一的服务出口发出去,主页面提供一个统一服务接口解析数据,并根据规范调用相应的方法
还有,就是版本控制的问题,为了尽量减少给第三方App带来影响,以上所有这些JS文件的版本都是采用向后兼容的策略,小版本使用服务器设置SQUID缓存特定频率的失效时间实现,大版本更新根据用户自己的需求手动更改
当然,以上可能不是最优的解决方案,只是希望能给你一些帮助和引导,我们也在逐步的改进我们的一些实现方式,比如版本控制这块儿,我们也有一些问题需要解决

具体的代码

主页面A的源码


代码如下:

Js代码
/*主页面A*/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>主页面A</title>
<script type="text/javascript">
function init(){
document.domain = 'bai.sohu.com';
alert('我是主框架,嵌入了第三方应用IframeB,下面开始加载应用');
var iframeTag = document.getElementById('frameB'),
iframeSrc = 'http://test.com/iframePage.html';

iframeTag.src = iframeSrc;
iframeTag.style.display = 'block';
};

function callback(h){
var iframeB = document.getElementById('frameB');
alert('IframeC调用我(主框架)接口,把IframeB的高度传给我,具体值是:' + h);
iframeB.style.height= h + 10 + 'px';
iframeB.src += '#'+ h
};
</script>
</head>
<body onload="init();">
<p>我是主页框架,我的域是:bai.sohu.com</p>
<iframe id="frameB" style="display:none;"></iframe>
</body>
</html>

iframeB(iframePage.html)的源码


代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>iframeB</title>
</head>
<body onload="init();">
<p style="height:500px;">我是三方应用,我的域是:test.com</p>
<iframe id="frameC" style="height:1px;width:1px;display:none;"></iframe>
</body>
</html>
<script type="text/javascript">
function init(){
alert('我是第三方App,下面开始创建和主框架同域的通信通道IframeC,并设置它的src,用#号传递高度值');

var iframeTag = document.getElementById('frameC'),
iframeSrc = 'http://bai.sohu.com/iframePageC.html#',
pageHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

iframeTag.src = iframeSrc + pageHeight;
iframeTag.style.display = 'block';

window.setTimeout(function(){
alert('主页面设置我(IframeB)的src,通过Hash(#)给我传递它收到的高度:' + location.hash);
},2000);
};
</script>

iframeC(iframePageC.html)的源码


代码如下:

<script type="text/javascript">
document.domain = 'bai.sohu.com';
alert('我(IframeC)收到iframeB通过参数(#)给我传递高度值,我现在调用主页面方法去设置IframeB的高度');
top.callback(window.location.href.split('#')[1]);
</script>

(0)

相关推荐

  • 使用postMesssage()实现iframe跨域页面间的信息传递

    由于web同源策略的限制,当页面使用跨域iframe链接时,主页面与子页面是无法交互的,这对页面间的信息传递造成了不小的麻烦,经过一系列的尝试,最后我发现有以下方法可以实现: 1. 子页面url传参 简单说来就是把所有需要传递的参数加到与主页面同源的url上,将子页面重定向到该url,然后主页面通过iframe的src获取这些参数 过程非常复杂,不建议使用这种方法 2. postMessage() postMesssage()是HTML5提供的一个基于事件的消息传输API,可以实现跨文本档.多窗

  • js iframe跨域访问(同主域/非同主域)分别深入介绍

    js跨域是个讨论很多的话题.iframe跨域访问也被研究的很透了. 一般分两种情况: 一. 是同主域下面,不同子域之间的跨域: 同主域,不同子域跨域,设置相同的document.domian就可以解决; 父页访问子页,可以document.getElementById("myframe").contentWindow.document来访问iframe页面的内容:如果支持contentDocument也可以直接document.getElementById("myframe&

  • 关于Iframe如何跨域访问Cookie和Session的解决方法

    最近做登录系统的整合,其中遇到的一个最关键的问题为在一个统一的后台里需要无障碍的访问另外一个系统后台,这个系统是第三方提供的一个加过密的系统,后台自动登录接口是自己分析出来的,没有单独提供,当从统一后台通过自动登录接口登录时,系统直接跳转到系统后台首页,后台登录成功后所跳转的URL这里没法指定,控制不了跳转的页面,如果在统一后台里需要链接到这个系统后台的另外一个页面,而非后台默认首页时,也就是将第三方系统后台的菜单功能放到我们这个统一后台里. 对于这样的一个需要,这里会遇到一个问题,为了能正常访

  • 利用iframe实现ajax跨域通信的实现原理(图解)

    在漫长的前端开发旅途上,无可避免的会接触到ajax,而且一般情况下都是用在同一域下的ajax请求:但是如果请求是发生在不同的域下,请求就无法执行,并且会抛出异常提示不允许跨域请求,目前我没有找到明确的资料说明这是为什么,我觉得应该是出于安全性的考虑吧.纵然如此,要实现跨域访问的话,方法还是有的,而且不只一种,在这里介绍其中一种解决方案:如何利用iframe完成ajax的跨域请求. 如下图所示:域a.com的页面request.html(即http://a.com/request.html)里面嵌

  • 使用postMesssage()实现跨域iframe页面间的信息传递方法

    由于web同源策略的限制,当页面使用跨域iframe链接时,主页面与子页面是无法交互的,这对页面间的信息传递造成了不小的麻烦,经过一系列的尝试,最后我发现有以下方法可以实现: 1. 子页面url传参 简单说来就是把所有需要传递的参数加到与主页面同源的url上,将子页面重定向到该url,然后主页面通过iframe的src获取这些参数 过程非常复杂,不建议使用这种方法 2. postMessage() postMesssage()是HTML5提供的一个基于事件的消息传输API,可以实现跨文本档.多窗

  • 如何设置iframe高度自适应在跨域情况下的可用方法

    在页面上使用iframe来动态加载页面内容是网页开发中比较常见的方法.在父页面中给定一个不带滚动条的iframe,然后对属性src指定一个可加载的页面,这样当父页面被访问的时候,子页面可以被自动加载.iframe的高度需要根据子页面的实际高度来进行调整.如果iframe的高度小于子页面的实际高度,超出的部分无法显示:相反,如果iframe的高度过高,则页面上会出现大量的空白区域.我们可以通过属性或者CSS来设置iframe的高度,当不确定子页面内容的高度时,也可以通过脚本来进行动态指定.但是如果

  • js跨域问题之跨域iframe自适应大小实现代码

    复制代码 代码如下: <body onload="javascript: setHeight();"> <script> function setHeight(){ var dHeight = document.documentElement.scrollHeight; var t = document.createElement("div"); t.innerHTML = '<iframe id="kxiframeagent

  • 关于iframe跨域POST提交的方法示例

    前言 以前在面试的时候经常遇到问关于跨域的事儿,所以自己对跨域有一定的概念性了解,知道什么是跨域以及解决跨域的方法,但是具体实际从来没有操作过,直到最近在公司项目中,遇到了一个需要使iframe跨域进行POST提交的实际案例,我才明白具体如何使用iframe进行跨域操作. 说到跨域,就不得不提起浏览器的同源策略. 同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互. 源 如果协议,端口(如果指定了一个)和主机对于两个页面是相同的,那么这两个页面就具有相同的源. 从这个定义可以看

  • iframe跨域与session失效问题的解决办法

    何为跨域跨域session/cookie? 也就是第三方session/cookie.第一方session/cookie指的是访客当前访问的网站给访客的浏览器设置的seesion /cookie, 会被存储在访客的计算机上.第三方session/cookie指的是当前访问的网站中会加载(嵌入)另外第三方的网站代码,例如促销广告,那么第三方网 站也会在访客的计算机上添加session/cookie,这种就是第三方session/cookie. 我的问题 在开发讯息在线产品(http://iap.p

  • IFrame跨域高度自适应实现代码

    复制代码 代码如下: var iframeids = ['memberIndexIframe','inquiryCenterIframe','everychinaBbsIframe']; var iframehide = "yes"; function dynIframeSize(){ var dyniframe = []; for(var i=0;i<iframeids.length;i++){ if(!document.getElementById) return false

随机推荐