最近同事詢問一個將 Webfocus 報表放入 iframe 的問題,雖然畫面會出來,但是有些報表中的操作項目卻出不來,Browser 的 Console 會噴以下的錯誤,
Uncaught DOMException: Blocked a frame with origin “http://192.xxx.xxx.xxx" from accessing a cross-origin frame.
at getPathNameObj (olapctl.js:72:97)
at getLoginStatus (olapctl.js:63:387)
at olapBaseWindowSetup (olapctl.js:648:113)
at olapOnloadFuncInitOCPLite (olapctl.js:633:90)
at olapJavaSetupCompleted (olapctl.js:798:422)
at olapWindowOnload (olap.js:83:232)
at eval (eval at ibigblInitTables_doOnLoad (http://192.xxx.xxx.xxx/ibi_apps/ibi_html/S22_15593321851F/javaassist/ibi/html/js/ibigbl.js:943:13), :1:1)
at ibigblInitTables_doOnLoad [as doOnLoad] (http://192.xxx.xxx.xxx/ibi_apps/ibi_html/S22_15593321851F/javaassist/ibi/html/js/ibigbl.js:943:13)
at ibigblOnLoad (http://192.xxx.xxx.xxx/ibi_apps/ibi_html/S22_15593321851F/javaassist/ibi/html/js/ibigbl.js:1507:20)
at onload (http://192.xxx.xxx.xxx/ibi_apps/run?PG_REQTYPE=REDIRECT&PG_MRsaved=false&PG_Func=GETBINARY&PG_File=ivyvkvqj.htm:90:32)
即然錯誤是 cross-origin frame ,那我們就先來看一下 X-Frame-Options,
The X-Frame-Options:HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a frame, iframe, embed or object. Sites can use this to avoid click-jacking attacks, by ensuring that their content is not embedded into other sites.
所以當我們用 iframe 把 google 網頁放進來時,它並沒有辦法正常的顯示,如下,
<iframe src="/https://www.google.com.tw/"></iframe>
會無法正常顯示是因為 Google Response 出來的 Header 是設定為 X-Frame-Options: SAMEORIGIN
Console 的錯誤訊息為
Refused to display ‘https://www.google.com.tw/' in a frame because it set ‘X-Frame-Options’ to ‘sameorigin’.
同事的 iframe 內容可以出現,只是有 js 的錯誤。而在本機可以,在另一台主機就會有錯誤。
判斷應該是 iframe 的安全性問題所導致的,SecurityError: Blocked a frame with origin from accessing a cross-origin frame上的建議是調整 JS 的做法,改用 window.postMessage 的方式,但因為 WebFocus 我們無法調整。另一個方式是停掉Browser same-origin policy,這也不可行。
即然 Client 不行…那就改用 Server 端吧。
因為它的錯誤是因為不同的主機,那就讓 iframe src 是同主機的位址就可以了。
所以可以在 IIS 上安裝 Application Request Routing(ARR)來啟用 反向代理(Reverse Proxy),
例如建立一個 google 的應用程式,並在該檔案目錄中放入以下的 web.config 內容,
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="https://www.google.com.tw/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
而原本 iframe link 到 google.com 就改成
<iframe src="/google"></iframe>
google 就正常地顯示在 iframe 之中,如下,
所以… 最後就利用 反向代理 來避掉這個問題,以上的解法希望對大家有所幫助。
X-Frame-Options
ASP.NET Security Headers
SecurityError: Blocked a frame with origin from accessing a cross-origin frame