2010-04-02 152 views
18

我正在維護一個這樣的應用程序:如何在幀之間進行通信?

有一個頁面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

回答

25

如果父頁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

2

如果要在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

7

如果頁面&框架不在同一個域中,則必須使用postmessage,因爲出於安全考慮,同一域策略禁止在不同域的頁/框之間進行正常的javascript通信。

postmessage是html5和works in all modern browsers (including IE8)的一部分。如果你需要支持舊版瀏覽器(特別是IE6/7),你可以使用jQuery postmessage plugin(它對舊版瀏覽器透明地回退到一些不錯的散列標記技巧)。

作爲一個旁註:不確定如果框架是邪惡的,有一些問題(可用性,SEO,...)與他們有關,但我做了一些研究和most of these can be tackled我認爲。

相關問題