在項目中,經常會使用到 iframe,把其它域名的内容嵌入到頁面中,這對于我們來說是個很友善的方法,但是,有時候,無可避免需要多個iframe間或者iframe與首頁面之間進行通信,比如交換資料或者觸發一系列事件。
本文将重點介紹如何在跨域的情況下進行iframe通信。首先,我們了解一下在同域情況下,iframe的通信方法。
frame同域通信
假設,www.a.com域的main.jsp需要與子頁面sub_1.jsp的互相通路,實作的功能如下:
(1)main.jsp通過iframe加載sub_1.jsp
(2)加載sub_1.jsp完成後,首頁面通過js讀取子頁面的标題顯示到首頁面的 p 标簽,另外,調用子頁面提供的方法 fun()
(3)子頁面讀取首頁面的标題顯示到 span 标簽
(4)點選子頁面的按鈕,調用首頁面的 fun() 方法
清單:main.jsp
清單:sub_1.jsp
frame跨子域通信
如果上面的sub_1.jsp頁面放在sub.a.com,同樣通過www.a.com的main.jsp的iframe載入sub_1.jsp
這時,通過浏覽器的控制台背景,可以觀察到報錯。
例如下面這種跨子域的操作是不允許的:
解決方法: 把首頁的域和子頁面的域設定為同一個二級域名下,比如a.com,它們之間就可以通路了:
(1)在main.jsp加上js代碼
(2)在sub_1.jsp加上js代碼
frame跨全域通信
html5中提供了window.postmessage這麼一種用于安全的使用跨源通信的方法,可以實作跨文本檔、多視窗、跨域消息傳遞。
postmessage(data,origin)方法接受兩個參數:
(1)data:要傳遞的資料,html5規範中提到該參數可以是javascript的任意基本類型或可複制的對象,然而并不是所有浏覽器都做到了這點兒,部分浏覽器隻能處理字元串參數,是以我們在傳遞參數的時候需要使用json.stringify()方法對對象參數序列化,在低版本ie中引用json2.js可以實作類似效果。
(2)origin:字元串參數,指明目标視窗的源,協定+主機+端口号[+url],url會被忽略,是以可以不寫,這個參數是為了安全考慮,postmessage()方法隻會将message傳遞給指定視窗,當然如果願意也可以建參數設定為"*",這樣可以傳遞給任意視窗,如果要指定和目前視窗同源的話設定為"/"。
接下來,我們完成一個簡單的示例,熟悉原理:子頁面(www.b.com)發送子頁面的标題到父頁面(www.a.com),父頁面接收參數,指派到付頁面的html文檔中。
清單:父頁面main.jsp
清單:子頁面sub_3.jsp
這樣就實作了上面所述的功能。既然,已經知道了如何使用postmessage,下面将抽取出來得到一個通用的子產品post_msg.js
如何使用? 假如main.jsp中有一個方法settitleval(arg)是對html标簽的指派,sub_3,jsp需要把子頁面的标題的值傳到父頁面settitleval方法中,完成指派。
(1)需要在main.jsp引入post_msg.js,并且暴露ettitleval方法
(2)sub_3,jsp引入post_msg.js,調用下面代碼即可。
<a href="https://my.oschina.net/thinwonton/blog/1058037">原文連結</a>