`

iframe跨域通信的通用解决方案 (摘抄)

 
阅读更多

 来自:http://www.alloyteam.com/2012/08/lightweight-solution-for-an-iframe-cross-domain-communication/

DEMO:点击这里

脚本下载:http://biqing.alloyteam.com/lab/messenger/messenger.js

GitHub:https://github.com/biqing/MessengerJS

 

 

 

2个信使的情况

 

 

此方案已有新版本, 请查看《iframe跨域通信的通用解决方案-第二弹!(终极解决方案)》。本文章可做技术学习供继续交流。

一、背景

在这个Web页面越来越丰富的时代,页面通过iframe嵌入其他的页面也越来越常见。但由于浏览器同源策略的限制,不同域之间属性和操作是无法直接交互的,所以在这个时候,开发者多多少少需要一些方案来突破这些限制。跨域问题涉及的地方也很多,如文档之间的消息通信、ajax请求、Cookie等,本文讨论的是iframe和父页面的消息通信。

 

二、现状

目前网上也可以找到各种解决方案(少说都有10+个,有兴趣的话可以去看看),对于现代浏览器来说,原生的postMessage API一定是不二的选择,所以各种方案的不同点均在于IE 6、7中的处理(不用兼容IE6、7的同志可以去看其他文章了)。当然这么多方案有各种优缺点,甚至有些只支持单向跨域,个人觉得实际意义不大。另外一些方案需要proxy.html这样的代理页面做中转,但是涉及服务器上的部署,并且对于多方合作来说还是有些麻烦。

三、思路

虽然不再复述现有的各种方案,但还是想交待一点上下文。相信网上看到最多方案就是利用location.hash或是window.name进行iframe的跨域通信:

location.hash会直接暴露在URL里,并且在一些浏览器里会产生历史记录,数据安全性不高也影响用户体验,所以不做考虑。另外由于URL大小的限制,支持传递的数据量也不大。

window.name相比来讲就好很多了,支持2M的数据量,并且当iframe的页面跳到其他地址时,其window.name值保持不变,副作用可以说是最小的。

讲到这思路也比较清晰了,咱们就用window.name呗,但问题又来了:只有两个页面同域时才能访问window.name。这个问题还好,只要把iframe改为与父页面同域就可以了。这又衍生了新的问题:这不是意味着只能单向通信了吗,iframe怎么向父页面发消息(不可能去改父页面的location吧)?在暗骂坑爹的同时偶然发现了一个很神奇的方法,就是想访问一个iframe的window.name时,只要将其location改为‘about:blank’即可,屡试不爽~没错这个“特性”可以视为IE6/7的一项安全性问题,但利用这个特性来进行跨域通信并没有实际的安全风险。

具体的实现见下图,在iframe的内部再创建一个iframe(我们称之为信使),父子页面轮询信使的window.name,父子页面各自使用变量保存window.name,轮询时发现有变化即被视为收到消息。基本原理就是这么简单,我们继续..

1个信使的情况

图1

作为一个通用的解决方案,我们的目标是提供一个js文件,封装通信的接口,需要通信的页面只要加载js文件就行。但在封装前,需要考虑更复杂一点的情况:当父子页面双方频率较高地双向通信时,如何进行支持?按照上述的方案,信使的window.name并没有读写锁的概念,这意味着消息很容易乱掉或被漏掉。所以更好的方案应该是:创建两个信使,分别负责”父–>子”和”子–>父”的消息传递,并且为了防止消息被冲掉,发送消息时会维护一个消息队列,在取消息时处理消息队列里的所有消息。见图2。

2个信使的情况

图2

四、封装

最后的封装就是加入了postMessage API的检测,另外也要判断是否为跨域,这样就满足了所有iframe通信的情况了。这里实现的信使只负责消息的监听和发送,所以在使用上是非常简单的:

 

// 父页面中

// 初始化信使, 告知与其交互的iframe引用

var messenger = Messenger.initInParent(iframeEl);

 

// 监听消息

messenger.onmessage = function (data) {

          ...

};

 

// 发送消息

messenger.send(message);

// iframe中

// 初始化信使

var messenger = Messenger.initInIframe();

 

// 监听消息

messenger.onmessage = function (data) {

      ...

};

 

// 发送消息

messenger.send(message);

具体使用可以参考下方的demo : )

五、总结

虽然国内也有人提过使用”about:blank”进行iframe通信的,但是代码的封装和可读性都不是太好,本方案是一日本人所提出,我觉得处理的很好,所以就拿出来和大家分享下。虽然尝试过优化轮询那一块,但暂时无果,有兴趣的朋友可以一起研究下~

分享到:
评论

相关推荐

    iframe跨域通信的通用解决方案-第二弹!(终极解决方案)

    标题中的“iframe跨域通信的通用解决方案-第二弹!(终极解决方案)”指的是在Web开发中,使用`iframe`元素进行跨域通信的一种高级技术。跨域通信是Web应用程序中常见的需求,特别是在需要集成不同来源的网页内容或者...

    iframe跨域通信解决方法

    ### iframe跨域通信解决方法 在现代Web开发中,跨域问题经常出现并困扰着开发者。尤其是在使用`iframe`嵌入不同源的内容时,主页面往往无法直接与`iframe`内的内容进行交互,这就需要一种解决方案来实现跨文档消息...

    完美解决iframe跨域问题

    总结,通过理解iframe跨域问题的本质以及各种解决方案,我们可以根据实际需求选择合适的策略。`window.name`跨域通信虽然存在一定的局限性,但在某些场景下能提供一种实用的跨域数据传递手段。在实际开发中,结合...

    解决JS跨域访问IFrame的解决方案

    "解决JS跨域访问IFrame的解决方案"这一主题关注的就是如何克服这个限制,使得在JSP页面中嵌入的跨域IFrame能够正常通信。下面我们将详细探讨这个问题以及可能的解决方案。 首先,理解同源策略是关键。同源策略是...

    单点登录跨域iframe互相通信方案.zip

    该压缩包文件"单点登录跨域iframe互相通信方案.zip"提供了一种解决方案,可能包含以下关键知识点: 1. **OAuth 2.0或SAML协议**:单点登录通常基于OAuth 2.0或Security Assertion Markup Language (SAML)等标准协议...

    iframe跨域解决方案

    综上所述,`iframe`跨域解决方案主要包括`postMessage`通信、`window.name`数据传递以及`CORS`策略。在实际应用中,开发者应根据具体需求和安全考虑,选择合适的跨域策略。同时,需要注意的是,虽然这些方法能突破...

    iframe 跨域解决方法

    总的来说,`iframe`跨域问题的解决方案依赖于你的具体需求和目标页面的可控程度。理解并正确使用上述方法,可以有效地解决跨域限制,实现`iframe`间的通信。在实际项目中,务必确保遵循最佳实践,同时注意安全性和...

    MessengerJS-master(iframe跨域通信)

    MessengerJS-master(iframe跨域通信) MessengerJS-master(iframe跨域通信)

    iframe 跨域访问session

    `iframe` 跨域访问`session`正是为了解决这一问题。 首先,让我们了解一下`session`和`cookie`的关系。`session`通常用于存储用户登录状态等临时信息,而`cookie`则作为`session` ID的载体在客户端和服务器之间传递...

    iframe跨域常用问题和iframe页面自适应

    在网页开发中,`iframe`...总结,理解和掌握`iframe`的跨域解决方案以及自适应策略,对于开发高效且用户体验良好的Web应用至关重要。在实际应用中,还需要注意安全性、性能优化等问题,以提供更优质的网页服务。

    js跨域解决方案

    4. **IFrame跨域通信**:利用`window.postMessage`方法,可以在属于不同源的两个IFrame之间进行通信。这种方法适用于页面嵌套场景,但不适用于跨域API调用。 5. **WebSocket跨域**:WebSocket协议本身支持跨域,...

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

    以前在面试的时候经常遇到问关于跨域的事儿,所以自己对跨域有一定的概念性了解,知道什么是跨域以及解决跨域的方法,但是具体实际从来没有操作过,直到最近在公司项目中,遇到了一个需要使iframe跨域进行POST提交的...

    iframe跨域通信--html5.postmessage

    总的来说,`iframe`跨域通信和`postMessage`是现代Web开发中解决跨域问题的重要工具,它提高了用户体验,增强了网页间的交互能力,同时也带来了安全性和灵活性的提升。理解和掌握这一技术对于开发者来说至关重要,...

    iframe跨域访问示例

    为了解决iframe跨域访问的问题,Web开发中引入了几种解决方案: 1. **CORS(Cross-Origin Resource Sharing)**:这是一种服务器端的方法,允许特定的资源被其他域的页面访问。通过设置HTTP响应头`Access-Control-...

    iframe跨域问题

    iframe跨域问题:Uncaught DOMException Blocked a frame with origin解决方法

    iframe 跨域 自动适应高度

    本文将详细讲解如何解决`iframe`跨域问题以及实现自动适应高度的功能。 1. **同源策略与iframe跨域** 同源策略是浏览器安全的一项基础机制,它限制了来自不同源的"文档"或脚本相互交互。当一个`iframe`加载的页面...

    iframe+postMessage实现跨域通信

    iframe+postMessage实现跨域通信 window.postMessage()方法安全地启用Window对象之间的跨源通信;例如,在页面和它产生的弹出窗口之间,或者在页面和嵌入其中的iframe之间。 

    Web应用跨域通信解决方案课件。

    跨域通信解决方案的课程旨在深入讲解这一领域的核心概念和技术,以便开发者能够理解和解决实际开发中遇到的问题。 首先,我们要理解"跨域"的基本含义。在Web浏览器的安全模型中,同源策略(Same-origin policy)是...

    Tomcat跨域请求资源解决方案.zip

    本资料包“Tomcat跨域请求资源解决方案.zip”显然是针对这个问题提供了一个具体的解决方案,主要聚焦于如何在Apache Tomcat服务器上配置以允许跨域请求。 Tomcat是Java Servlet容器,广泛用于部署Java Web应用程序...

Global site tag (gtag.js) - Google Analytics