17

我正在维护一个类似这样的应用程序:

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

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

现在我的解决方案是重定向到 AllOrders,比如 client.MyCompany/Orders

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

我不觉得这个解决方案是最优的,但我想不出别的了!我已经尝试将所需的 url 放在页面 A 中的隐藏 Div 中(因为 A 确实知道所有信息),然后尝试从 B 读取页面的整个 DOM 以找到它....不幸的是,我只能访问框架 B 的 DOM ...(我尝试使用 jquery)。

我知道框架是邪恶的,但它是这样写的……有什么想法吗?

谢谢!

4

3 回答 3

25

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

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

您将无法从父页面 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(通过分配window.domain = "foo.bar.com" 在 A 的脚本中)。然后页面 A 将作为页面 B 的对等点,然后两者可以根据需要访问彼此的数据,即使从技术上讲 A 是从与 B 不同的域提供服务的。我也写了一篇关于降低域的文章。

域降低只能剥离最里面的子域以在根域的上下文中运行。您不能将 A.foo.bar.com 更改为 abc.com。

将域降低到公共根域也存在轻微风险。当您在自己的子域中操作页面时,您的 html 和脚本将与公共根域之外的其他子域隔离。如果其他子域之一中的服务器受到威胁,它不会真正影响您的 html 页面。

如果您将页面的域降低到公共根域,那么您会将您的内部暴露给在公共根域上运行的脚本以及来自其他子域的脚本,这些子域也将其域降低到公共根域。如果其他子域之一中的服务器受到威胁,它将可以访问您的脚本的内部,因此它也可能已经破坏了您的子域。

于 2010-04-05T05:45:10.460 回答
7

如果页面和框架不在同一个域上,您将不得不使用postmessage,因为出于安全考虑,同域策略禁止不同域的页面/框架之间的正常 javascript 通信。

postmessage 是 html5 的一部分,适用于所有现代浏览器(包括 IE8)。如果您需要对旧版浏览器(特别是 IE6/7)的支持,您可以使用jQuery postmessage 插件(对于旧版浏览器,它显然会退回到一些不错的标签技巧)。

并且作为旁注:不确定框架是否是邪恶的,有一些与它们相关的问题(可用性,搜索引擎优化,......),但我做了一些研究,我认为其中大部分都可以解决

于 2010-04-04T03:57:51.930 回答
2

如果您想在 javascript 中的框架之间进行通信,您可以使用“父级”:

如果帧 A 有一个变量值,例如:

var orderNo = 2;

对于框架 B 阅读它将指

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

(假设帧 A 是第一个声明的帧)

因此,您可以在每个框架内设置其他框架可以读取的全局变量,因此您可以在老式 javascript 中获得顺序 #(从未在 jquery 中尝试过)。

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

于 2010-04-03T00:16:50.950 回答