iframe跨域javascript訪問

來源:互聯網
上載者:User
問題抽提:首頁A.html在域www.aaa.com中,要用Ifame嵌入在域www.bbb.com中的B.html網頁。現在需要讓B.html中進行某一操作之後,調用A.html中的js函數onExcute。如果進行一般的操作在B.html中使用"window.parent.onExcute();"調用根本不會被執行,也不提示錯誤,在調試時會得到"Permission denied
to access property"的提示資訊。如果是在同域的兩個頁面這麼使用沒有問題,但是在跨域環境下就會出現這樣的情況,這就是所謂的“iframe跨域問題"。

在A.html中

 

<script type="text/javascript">function onExcute(wellStr){ //事件響應               }</script>  <iframe id="bFrameId" src="http://www.bbb.com/B.html" width="100%" height="100%"></iframe> 

在B.html中的某一事件響應函數中,需要調用A.html中onExcute(……)方法。 

 

問題分析:

(1)A.html與B.html跨域,在B.html使用window.parent.onExcute(……),會因跨域訪問,受瀏覽器“強制”限制。

(2)網上很解決“iframe高度自適應”的解決方案,都通過B.html的window的location是可以公用訪問的,location.hash用來存放需要需要傳遞的參數。但是本問題是方法調用,需要觸發js函數的調用,而不僅僅是參數的擷取。基於此也有極差的解決辦法是,監測B.html中location.hash值的變化,在A.html中寫一函數定時檢測(如一秒鐘)此值,一旦B.html中響應事件之後將參數放於location.hash中,那麼A.html在周期內會檢測到此值的變化。

(3)網上還有解決解決方案:其一是欺騙法,兩個網頁document.domain儘管不一樣,可以強制使值一樣為“aaa.com",以此達到欺騙IE的目的(其它瀏覽器不一定起效)。不適用於原因首頁面使用大量的指令碼架構,會影響其它部分功能的使用。其二是"同域iframe無限制“的方法,就是由於跨域指令碼中對parent訪問iframe的屬性無限制。就是在B.html中再嵌入iframe(內容是來自與A.html同域的網頁C.html),特別適用於解決高度自適應的問題(C.html可以直擷取B.html的iframe寬高資訊,而A.html與C.html是同域的,可以js函數調用不會受限)。

 但是,仍然無法實現事件的即時觸發。

解決方案:結合以上兩種方法(location.hash儲存參數,同域iframe指令碼調用無限制)

 

(1)在B.html中觸發事件(例如函數btnEvent())中,修改C.html的location.href。其中的hash是url後面的從"#"開關的部分,用於儲存參數,hash值的改變不影響iframe的重新整理;而url後面的參數"redirected=true"用於修改url(實際上還是本頁),主要用於觸發cFrame重新載入(即C.html中的window.onload事件)

function btnEvent(){var str = 'well_1,well_2';//注意: frames擷取C.html的frame時, cFrameId 是iframe的name屬性//其中‘redirected=true’故意添加參數,強迫C.html的頁面重新整理,響應onload事件document.getElementById('cFrameId').setAttribute('src', 'http://www.aaa.com/C.html?redirected=true' + '#' + str);}<iframe id="cFrameId" name=' cFrame' src="http://www.aaa.com/C.html" style="display: none"></iframe>

 

(2)在C.html中,使用頁面載入過程中響應事件,通過url的參數判斷當前載入是否是B.html的操作引起的,如果是,則需要馬上響應A.html中的onExcute()函數,然後需要再次重新整理當前頁,來恢複url中的無參狀態,以保證B.html中通過修改url能夠再次觸發C.html重新整理頁面載入onload事件。

 

window.onload = function(){var url = window.location.href;if(url.indexOf('redirected=true') > -1){              var str= location.hash;      //以#開頭的資訊if(str.length > 1){str= str.substring(1);}window.parent.parent.onExcute(str);window.location.href = 'http://www.aaa.com/C.html';    //恢複狀態,以方便B.html再次響應事件}}

 

總結:在B.html中能夠調用A.html中的js函數的根本原因,是B.html能夠控制其內嵌iframe(cFrame)的location,從而導致其內嵌iframe(因重新整理頁面)觸發的onload事件。而從B.html傳遞的參數,則是通過url尾碼加(以"#"開開頭的)hash值來實現的,實際上,也可以不用hash,(既然用到了參數,何不用兩個參數呢?)用兩個url參數就可以,一個用來表示狀態(如上面的"redirected=true"),一個用來傳遞B.html要調用A.html中js函數的參數(用來替換上面在url後面綴加hash值用來傳參的方法)。同理,如果反過來,希望A.html調用B.html中的js函數,則需要通過修改bFrame(B.html所在的iframe)中location,來觸發B.html的載入,在onload時通過url參數來判斷是否該調用此B.html中的js函數。這樣做可以解決這樣的問題,但缺陷是B.html重新整理太頻繁,每次調用都需要重新整理B.html兩次。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.