瀏覽器的IFrame無窮迴圈防呆
在射茶包的過程中,發現了一個有趣的瀏覽器行為。
程式碼如下,按下Button會在IFrame元素中開啟目前所在網頁。會寫成這種架構是打算讓一個網頁同時扮種兩種角色,不必為了一個小測試搞出兩個HTML檔案來。實際的測試中,我用if (parent != window)判別網頁是否在IFrame中被開啟,執行不同的功能。這裡只為了突顯瀏覽器的行為特性,我把程式碼簡化到最少。
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<iframe id="f" src=""></iframe><br />
<input type="button" value="showFrame"
onclick="document.getElementById('f').src=location.href;" />
</body>
</html>
我本來預期按下Button後,IFrame中會出現同一個網頁,結果不然!
使用IE8進行測試,按下Button後,啥事也沒發生,IFrame中空白一片,由網頁屬性發現它仍維持about:blank,也就是src並未被改變。如果把src設定改為http://www.google.com http://www.bing.com(身為MVP,偶爾也要從事一下政令宣導莒光教學咩)則行為正常。看來,問題出在location.href。接著我把location.href改成httq://localhost/lab/recursive.htm,依然無效,但再改成recursive.htm?x=1,則可以順利開啟。
經過推敲,我覺得這是一種安全機制,防止網頁內嵌自己,內嵌那一分又再內嵌了自己,形成無窮迴圈會吃光資源。打個比喻,如果將DV的即時影像輸出到電視上,再用DV去拍電視,畫面就會變成一層包一層,層層相包無窮無盡的電視框。還想像不出來的人,我們請基努李維親自示範一下類似的效果。

就像程式的遞迴呼叫Recursive有相對的防呆,瀏覽器也要設法防止這種內嵌無窮迴圈發生! 好奇心起,用各家瀏覽器做了一下測試,發現有三種結果:
IE、Opera: 完全不允許內嵌自己,iframe.src = location.href 無反應。
Chrome、Safari: 只能呼叫一層,內嵌的那一層便不再允許內嵌自己。
Firefox: 會出現錯誤訊息--uncaught exception: [Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIDOMHTMLIFrameElement.src]" nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)" location: "JS frame :: httq://localhost/Lab/Recursive.htm :: onclick :: line 1" data: no]
以上是我的心得報告。