开发人员提示

iframe跨域策略问题

经过 2011年1月24日 12 Comments

如果您是需要使用跨域iframe的前端开发人员,则会了解疼痛。你可以写一点漂亮的代码并让它在Firefox上工作,但它会在IE上崩溃。你会认为这很容易–Facebook,Twitter和所有其他酷孩子正在做的!好吧,不太。

在Cakemail的情况下,我们目前正在构建一个平台,使我们的用户能够在他们的网站上直接在其网站上创建表单(思考电子邮件列表订阅表格)。所以基本上,我们需要在父母和孩子中拥有JavaScript控件。

根据嵌入,我们有2个问题要解决。一个是动态地改变iframe高度(在地狱中没有办法,我们将在数据库中保存iframe高度)。有时,根据我们网站嵌入的用户的功能,我们需要实际重定向父页面。

访问Cakemail Next-Gen for开发人员访问Cakemail Next-Gen for开发人员

为什么这么难?

安全: 一世’m sure I don’如果它可以访问您的文档,真的必须告诉您入侵者可以对您的网站做些什么。它可以将自己绑定到您的登录过程中,只需获取所有用户的电子邮件/密码,重定向您的网站等。这就是为什么实现跨域通信的原因不被轻描淡写。

即使您对此进行了正确,您必须考虑可能会发生什么,如果嵌入式脚本泄露。特别是如果您将该脚本嵌入在其他不是您的其他网站中!

访问父窗口和文档

访问父文档真的很简单,当您在同一域时,您可以快速完成 window.opener.myparentFunction(), 和你’re done.

但是在做这个跨域?不那么容易。你’ll沿着: 子文档无权访问父文档。事实上,关于如何实现它的网络上有很多文档,但问题是它经常过时,通过往往仅在浏览器夫妇中工作的解决方案。

做这件事:iframe中的iframe中的iframe

一个聪明的想法,在前段时间出现了–在您的子窗口中嵌入IFRAME’s位于父窗口的同一域名。它的工作原理,大部分时间,但是这种技术都有变体,其中一些工作和一些唐’T。一些变体涉及使用哈希传递数据(#)的URL,如果您想传递大量数据,这真的很糟糕,并且在IE中发出令人讨厌的噪音和可怕的浏览历史。

但请记住,这仍然是一个 h。你’使用有点聪明的想法绕过保护,并且总是有机会在一天内停止使用浏览器更新。

老黑客的一个很好的资源

这个网站 真的详细了解如何制作IFRAME黑客工作。它’如果您想详细了解IFRAME跨域策略工作,则非常有用。

html5方式

啊HHH HTML5,所有问题的救主–正确的?对于跨域问题,HTML5实现了一个很好的新JavaScript方法, 后期.

window.postmessage. 专门实施以安全地解决跨域策略问题(以及尽可能安全..)。这里’是什么沟通看起来像:

它配备了2个选项,使其尽可能安全,原点和来源。原点是消息域原点和源是对窗口对象的引用。

IE怎么样?

PostMessage在IE8中,但是它’s not in ie7 &IE6(显然)。如果您需要支持那些浏览器,您将不得不依赖另一种技术。

您可以获得真正完整的描述和后期的示例 Mozilla JavaScript文档网站.

像往常一样,对于我们需要妥协的良好的跨浏览器解决方案

与DOM的很多东西一样,它交叉浏览器的最佳方法是使用最佳解决方案,并依赖于旧浏览器的黑客。

幸运的是,这正是什么 EasyXDM. 为你做了。这个库是(或已经)由大量网站使用,包括推特和Disqus!它为您提供了一个漂亮的API,无处不在。让’s have a look:

 

easy怎么样,Easyxdm如何工作它的魔力?

您认为EasyXDM使用简单的IFRames技巧在IE7中工作&IE6,但事实上它使用了更聪明的黑客。它使用IE仅协议(某种VBScript),使得跨域通信成为可能的nixtransport。

“因此,此实现包装在VBScript类中使用的JavaScript对象。由于VBScript对象以JavaScript传递为COM包装器(如DOM对象),因此它们对JavaScript的不透明(除了它们暴露的界面之外)。因此,这提供了一种安全的运输方法。最初基于FrameSelementTransport,其与此方法共享一些相似之处。“

限制

我注意到使用此库的一个清晰限制是加载子窗口而不被嵌入父级,使EasyXDM抛出JS错误。论坛有方法可以使用第三个窗口来纠正这一点’S不是真的很方便,我也用OnReady选项进行了一些测试。它似乎首先工作,但无论如何,它有时仍然抛出错误。

对于它是什么’S值得,它仍然是我发现的最强大的图书馆,我发了一条1MB的信息,即使在IE7,它仍然通过它真正快速。

那’s it!

希望这可以帮助您获得所有跨域沟通!

这件作品是由Cedric Dugas,Cakemail编写的’S接口开发人员。您可以在Twitter上遵循CEDRIC @Posabsolute..

Please wait...

加入讨论 12 Comments

  • 谢谢提到EasyXDM–即使你说出那里最强大的图书馆,许多人仍在提倡XDM的糟糕习惯。

    如果您有任何问题或想法,请使用邮件列表或创建问题,将它们带到我的注意力–我的目标是尽可能好,可以是ðÿ™,

    关于`onread`功能–你能举报这个问题的性质吗?它直接相关吗?当您导航内部框架时(不支持,而且由于原因在邮件列表中无数次表示)?

    Please wait...
  • CEDRIC. 说:

    嘿Ã~yvind,

    是的,它从它导航内部框架时直接相关。起初我认为它有一段时间,我可能会误。

    除此之外,我们目前没有任何问题,它的摇摆! ðÿ〜‰

    Please wait...
  • EasyXDM听起来非常有用–谢谢你的参考。

    It’但是,值得注意的是,如果您只需将父或其他窗口导航到新的URL,则可以在没有任何特殊技巧的情况下执行此操作。只需分配到父级或任何内容。那里’s没有跨域限制*将*写入window.location属性,仅在*读取*中。

    这就是流行的片段标识符技巧如何运作 –一个窗口写入另一个窗口的哈希部分’s URL(它可以做跨域),另一个窗口使用计时器来观看哈希的变化。

    Please wait...
  • 乍得 说:

    在这篇文章中的GRAT时间。我需要在接下来的几天里看待这一点。谢谢!

    Please wait...
  • DR_ROOT. 说:

    THX 4分享!

    Please wait...
  • […] iframe跨域策略问题和html5解决方案。 […]

    Please wait...
  • yinch. 说:

    嗨Cedric,谢谢你的文章…我一直在阅读跨域问题几周,大多数解决方案都涉及我们更改父域脚本,但在Facebook的情况下,父脚本来自Facebook,我们无法访问它,它内部创建它我们的FB应用程序的iframe,所以所有解决方案都无法使用,我在这里错了吗?谢谢。

    Please wait...
  • 肯契约 说:

    一个注意如果在IFRAME中打开的页面使用PHP(可以使用其他动态LANAGUAGES)如果您的服务器有$ _SERVER [‘HTTP_REFERRER’]可用,您可以在要打开的页面中使用此选项以获取父页面的完整URL和查询字符串。然后将此设置为您在iframe中打开的页面中的变量,并且您有父网址。

    Please wait...
  • 我不明白第3点。

    你怎么能在远程iframe内部加载本地iframe?

    我的意思是,它陷入困境?

    我理解除了这个之外的所有步骤。

    Please wait...