如何在帧之间进行通信?

问题描述:

我正在维护一个这样的应用程序:如何在帧之间进行通信?

有一个页面A带有一个显示页面B的框架。现在页面B是一个完全不同的产品在一个单独的域中的一部分。

现在,他们希望当点击B中的一个选项时,整个页面被重定向到A中的另一个页面。问题是A的url类似于www.client.A.com/Order/Details/123,当我们点击时它应该重定向到www.client.A.com/Order/Edit/123之类的东西,但是B不知道关于A的任何信息。它不知道当前选择了哪个订单#或者关于A的任何信息。页面A拥有B框的人知道它。

现在我的解决方案是只重定向到AllOrders所以像client.MyCompany /订单

但由于B不知道哪个client是调用它(它是一个多租户应用程序),我将它添加到webconfig中。 (所以每个客户端都有自己的具有不同值的webconfig)。

我没有找到这个解决方案最佳,但我想不出其他任何东西!我已经尝试将所需的网址在页面A中隐藏的Div(因为A确实知道所有信息),然后尝试从B读取整个页面的DOM以找到它....不幸的是,我只能访问框架B的DOM ...(我试着用jQuery)。

我知道框架是邪恶的,但这是如何写...任何想法?

谢谢!

+1

页面A处于与B不同的域吗? www.foo.com vs www.bar.com? – dthorpe 2010-04-03 00:02:31

+1

+1不抱怨不得不使用其他人的框架! – amelvin 2010-04-03 00:18:35

+0

@dthorpe是的,他们在不同的域名 – 2010-04-04 04:48:14

如果父页A和iframe页B在不同的域中,您将无法通过B的父属性访问方法或字段,A中的脚本也不能访问B的内容,也不会能够在A和B之间共享全局变量。页面A和页面B之间的边界是浏览器安全模型的关键部分。正是通过阅读银行网页的JavaScript的内部变量,防止evil.com包装您的在线银行网页并窃取您的账户信息。

如果您拥有需要最新一代浏览器的奢华,可以使用此处其他答案中提到的postmessage技术。如果您需要支持旧浏览器,则可以在浏览器中使用跨域客户端脚本技术传递少量信息。其中一个例子是使用iframe在外部页面A和内部页面B之间传递信息。这并不容易,涉及很多步骤,但可以完成。我在此前写了一个article

您将无法从父页面A监视B的iframe中的点击次数。这违反了多个级别的浏览器安全策略。 (单击劫持)您无法看到B的URL何时更改 - A可以写入iframe.src属性来更改URL,但是一旦iframe.src指向与A域不同的域,A不能再读取iframe.src属性。

如果A和B位于同一根域的不同子域中,则可能有机会将该域“降低”到公共根目录。例如,如果外部页面A托管在子域名A.foo.bar.com中,并且B托管在子域名foo.bar.com中,则可以将页面A中的域名降低到foo.bar.com(通过分配A脚本中的window.domain =“foo.bar.com”)。然后,页面A将作为页面B的同行,然后二者可以根据需要访问彼此的数据,即使A在技术上由不同于B的域服务。我也写了一篇关于domain lowering的文章。

域降低只能剥离最内层的子域以在根域的上下文中操作。您不能将A.foo.bar.com更改为abc.com。

将域降低到通用根域也存在轻微风险。当您在自己的子域中操作页面时,您的html和脚本将从其他子域中分离出公共根域。如果某个其他子域中的服务器受到攻击,它并不会真正影响您的html页面。

如果将页面的域名降低到公共根域,则会将您的内部公开给运行在公共根域中的脚本,并从其他子域中将脚本放到公共根域的脚本公开。如果某个其他子域中的服务器遭到入侵,它将有权访问您的脚本内部,因此它也可能危及您的子域。

+0

感谢您的信息:((至少我发现我的问题通过使用服务器端配置文件..不太优雅/自动,但它的工作发现解决方法) – 2010-04-05 15:57:52

+0

+1良好的答案。 – amelvin 2010-04-13 11:35:53

+0

+1为您的文章,在特别是xhr部分 – Christophe 2013-02-23 20:25:17

如果要在JavaScript可以使用“父”的帧之间进行通信:

如果帧A具有可变的值,例如:

var orderNo = 2; 

对于帧B读它,将参考到

var frameA_orderNo = parent.frames[0].orderNo; 

(假定帧A被声明的第一帧)

所以你可以在每个框架中设置其他框架可以读取的全局变量,因此你可以用老式的javascript(从未在jQuery中试过)获得命令#。

哇框架 - 从来没有想过我会再考虑他们。

+0

谢谢! 我知道我也这么认为! 关于设置变量...我没有真正与JavaScript工作很多..我将如何设置全局变量? 谢谢! – 2010-04-03 00:23:39

+0

只要你不把变量放在一个函数中,它们就会有页面范围 - 所以只需在javascript的顶部声明它们,它们就可用。同样的技术应该允许你在另一个框架中运行方法,例如parent.frames [0] .methodname(); – amelvin 2010-04-03 22:42:22

+0

谢谢,我必须等到星期一才能尝试/接受:) – 2010-04-04 04:51:49

如果页面&框架不在同一个域中,则必须使用postmessage,因为出于安全考虑,同一域策略禁止在不同域的页/框之间进行正常的javascript通信。

postmessage是html5和works in all modern browsers (including IE8)的一部分。如果你需要支持旧版浏览器(特别是IE6/7),你可以使用jQuery postmessage plugin(它对旧版浏览器透明地回退到一些不错的散列标记技巧)。

作为一个旁注:不确定如果框架是邪恶的,有一些问题(可用性,SEO,...)与他们有关,但我做了一些研究和most of these can be tackled我认为。