項目中有個需求是在前后端分離的情況下,前台頁面將后台頁面加載在預留的iframe中;但是遇到了iframe和主窗口雙滾動條的情況,由此引申出來了問題:
只保留單個滾動條,那么就要讓iframe的高度自適應,而從主頁面顯然直接取不到iframe的值,因為這是跨域的(前台頁面與后台頁面不在同一個IP地址或者同一個端口),嘗試訪問會報錯:
Blocked a frame with origin "http://7.35.0.8:8080" from accessing a frame with origin "http://7.35.0.9:8080".Protocols, domains, and ports must match.
這本質上是跨域問題
解決跨域問題的方法大致有以下幾種
1.jsonp
2.hash
3.postMessage
4.websocket
5.cors
具體的使用方式和原理的文章有很多,而就應用場景而言,iframe間通信最完美的辦法莫過於postMessage了。
postMesasge是html5標准的方法,ie10+瀏覽器都支持,ie8/9部分支持。以下是部分實例:
//主頁面 向 iframe傳遞事件 //主頁面
var frame = document.getElementById('iframeId');
// postMessage接收兩個參數,第一個表示信息,可以傳遞字符串或者對象,我用的對象。refresh 是目標頁面監聽事件的key,對象內可以傳遞多個key;第二個參數表示目標源,*表示所有,但不安全,建議使用具體地址
frame.contentWindow.postMessage({refresh:'id'},'*');
//iframe頁面 window.addEventListener('message',function(event){
// event.origin --發送者的源
// event.source --發送者的window對象
// event.data --數據
if(event.data.refresh){
//此處執行事件
}
})
//iframe向主頁面傳遞事件
//iframe頁面 window.parent.postMessage({refresh:'id'},'*'); //主頁面 window.addEventListener('message',,function(event){ if(event.data.refresh){
//此處執行事件
}
})
新開頁面時也能用這個方式向父頁面傳遞事件(ie8/9不支持)
window.opener.postMessage({refresh:'some message'},'*')