這是最近跟老IE纏鬥衍生的副產品。

雖然已研究出用document.domain克服無法與IFrame跨站台網頁溝通問題,但實務上常不免會遇到使用IP、機器名稱或別名連上網站的場合,document.domain法只適用URL採FQDN完整網域名稱且後段網域相同的情境,實用性大減。

針對IFrame跨站台溝通,浏览器同源政策及其规避方法一文提到三種解法:

  • window.name
  • 跨文件傳輸API(Cross-Document Messaging)
  • 片段識別碼(Fragment Identifier,指xxx.aspx#yyy,#號之後的部分,可透過location.hash取回)

Cross-Document Messaging API是HTML5時代產物,IE5/IE7相容模式玩不起,直接跳過。window.name沒有資料長度限制,但IFrame每次載入網頁只能傳一筆資料(參考),無法持續溝通,用法受限。location.hash做法利用父網頁與IFrame可以設定對方location(只設定不讀取即不違背同源政策)且xxx.aspx#aaa改為xxx.aspx#bbb不會重新載入網頁的特性,巧妙實現跨站台父網頁與IFrame雙向溝通。大部分瀏覽器有onhashchange事件即時監控location.hash變化,IE8以下則要自己寫setInterval監測,倒也不難解,如此就算通吃所有IE模式。上吧,location.hash,就決定是你了。

寫完雛型實測可行後,為方便應用我抽取成程式庫,命名為HashTalkie(Hash對講機),感覺還有未涵蓋情境跟改善空間,索性把程式碼放上Github,分享之餘也蒐集回饋,有利於持續改版強化。

https://github.com/darkthread/HashTalkie

程式碼及說明已放在Github,有興趣的朋友請自取。

另外我也弄了Live Demo,如以下示範,htmlpreview.github.io的parent.html內嵌來自rawgit.com的child.html,跨站台傳送蘭亭集序跟關公千里走單騎呢,我沒唬爛吧!XD


Comments

# by 布丁布丁吃布丁

原來如此,所以用hash還是比較好的選擇啊 而且感謝您的這篇讓我知道IE8以下沒有onhashchange事件,難怪我之前程式在IE上運作都怪怪的。

# by

您好,拜讀了您的文章小弟非常敬佩 有個問題想請教一下, 為何跨站的情況下child.html執行parent.window.location = (this.targetUrl + "#" + data); 沒有被瀏覽器擋呢 我無論如何都取不出來,謝謝.

# by Jeffrey

to 白,href 不能跨站讀取,但可以跨站更改。依 HTML 規範 https://www.w3.org/TR/2017/WD-html52-20170228/browsers.html#dom-location-href The href attribute setter intentionally has no security check.

# by

感謝解答

Post a comment