最近幾天在做將之前的WebForm項目集成到新的MVC項目中,在新的MVC項目上要能夠訪問WebForm頁面,一開始想着這中嵌套的會有跨域的問題,所以MVC中使用frame來進行布局,以為能避免frame的跨域問題,可是昨天還是遇到了,項目采用常見左側手風琴導航右側顯示內容,之前WebForm的左側也是導航,是樹形導航,而且樹有好多層,新的MVC的左側導航只有二級,右側是用jquery.cleverTabs.js來做的卡片式頁面,jquery.cleverTabs.js里面有對跨域進行處理,所以二級以內的樹直接新增選項卡就行了,但有的節點比較深,當點擊二級時需要在選項卡頁面再增加一個樹形導航,於是這樣問題就來了。正常的如果沒有增加樹形導航的,可以直接通過addtab(url)來在右邊的選項卡頁面顯示,但增加了樹形導航之后就會有兩個url,所以不能直接通過jquery.cleverTabs.js添加WebForm的url。我這里又增加了一個頁面,讓jquery.cleverTabs.js打開新增的頁面,在新增的頁面中又嵌套<frameset></frameset>,左邊是樹形導航,右邊是WebForm頁面。現在要實現的效果是點擊樹形導航的節點獲取url來改變右側WebForm的頁面。如下圖:左側類似一個導航樹,右側是其他域的一個頁面。當點擊左側的按鈕時重新設置右邊的url顯示其他頁面。
a頁面
<frameset cols="50%,50%" id="mainframe" name="mainframe"> <frame id="leftFrame" name="leftFrame" src="b.html" /> <frame id="rigthFrame" name="rigthFrame" src="http://www.baidu.com"/> </frameset>
b頁面
在b頁面點擊按鈕讓右側顯示其他的url,開始使用下面的代碼,想着直接設置右側frame的src應該就可以了,可是確沒一點效果。F12查看出現下面的錯誤.
Uncaught DOMException: Blocked a frame with origin "http://localhost:63342" from accessing a cross-origin frame.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Title</title> <script src="jquery-3.2.1.min.js"></script> <script type="application/javascript"> $(function () { $('#btnTest').on('click',function () { self.parent.frames["rigthFrame"].src="http://www.w3school.com.cn/index.html"; }) }) </script> </head> <body> <div><input type="button" id="btnTest"></div> </body> </html>
剛開始出現覺得挺納悶,為什么設置屬性不起作用呢?自己也查了下,說是為了安全起見,瀏覽器禁止這樣的操作,只能讀,不過想想也是,如果允許這樣的操作,那就可以隨隨便便的改變下別人的頁面,這樣是很不科學的。那怎么能改變右側的顯示呢?網上說的也有好幾種解決的方法。當時我也是一頓好找,現在回過頭來再看,其實可以發現為什么<frame src='XXXX'>這樣就可以顯示。我們也可以動態創建一個frame,然后設置src,這樣就能把想要的頁面獲取到,獲取到之后就是顯示的問題了
<frame id="rigthFrame" name="rigthFrame" src="http://www.baidu.com"/>
b.html左側頁面 按鈕點擊執行父窗體方法openframe(url)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Title</title> <script src="jquery-3.2.1.min.js"></script> <script type="application/javascript"> $(function () { $('#btnTest').on('click',function () { // self.parent.frames["rigthFrame"].src="http://www.w3school.com.cn/index.html"; self.parent.openframe("http://www.w3school.com.cn/index.html"); }) }) </script> </head> <body> <div><input type="button" id="btnTest"></div> </body> </html>
a.html 頁面 在openframe(url)中動態創建了一個frame,然后設置url,並將它添加到frameset子節點中,此時已經可以把想要的頁面獲取到了。只是沒顯示出來。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Title</title> <script src="jquery-3.2.1.min.js"></script> <script type="application/javascript"> function openframe(url) { var frame=document.createElement('frame'); frame.src=url; frame.name="rigthFrame"; frame.id="rigthFrame"; self.parent.frames["mainframe"].appendChild(frame); } </script> </head> <frameset cols="50%,50%" id="mainframe" name="mainframe"> <frame id="leftFrame" name="leftFrame" src="b.html" /> <frame id="rigthFrame" name="rigthFrame" src="http://www.baidu.com"/> </frameset> </html>
當我們通過瀏覽器刪除第二個frame時見證奇跡的時刻到了。
刪除之后就顯示出了新的頁面
上面是通過瀏覽器調試刪除了,現在只要通過代碼將其刪除那就大功告成了。一行代碼搞定。
$('#rigthFrame').remove();
下面是完整的代碼父頁面a.html、子頁面b.html
a.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Title</title> <script src="jquery-3.2.1.min.js"></script> <script type="application/javascript"> function openframe(url) { var frame=document.createElement('frame'); frame.src=url; frame.name="rigthFrame"; frame.id="rigthFrame"; $('#rigthFrame').remove(); self.parent.frames["mainframe"].appendChild(frame); } </script> </head> <frameset cols="50%,50%" id="mainframe" name="mainframe"> <frame id="leftFrame" name="leftFrame" src="b.html" /> <frame id="rigthFrame" name="rigthFrame" src="http://www.baidu.com"/> </frameset> </html>
b.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Title</title> <script src="jquery-3.2.1.min.js"></script> <script type="application/javascript"> $(function () { $('#btnTest').on('click',function () { // self.parent.frames["rigthFrame"].src="http://www.w3school.com.cn/index.html"; self.parent.openframe("http://www.w3school.com.cn/index.html"); }) }) </script> </head> <body> <div><input type="button" id="btnTest"></div> </body> </html>
對於分布式應用來說,frame跨域是一個情況,還有session、cookie共享的情況也要考慮。這些都是跨域的問題。