防止網頁被嵌入框架的程式碼(續)

阮一峰發表於2010-08-15

兩年前,我寫過一段程式碼,防止網頁被嵌入框架(Frame)。

<script type="text/javascript">

  if (window!=top) // 判斷當前的window物件是否是top物件

  top.location.href = window.location.href; // 如果不是,將top物件的網址自動導向被嵌入網頁的網址

</script>

這段程式碼是有效的。但是,有一個問題:使用後,任何人都無法再把你的網頁嵌入框架了,包括你自己在內。

於是,我今天就在考慮,有沒有一種方法,使得我的網頁只能被嵌入我自己的框架,而不是別人的框架?

表面上看,這個問題很簡單。只要做一個判斷:當前框架和頂層框架的域名是否相同,如果答案是否,就做了一個URL重定向。

if (top.location.hostname != window.location.hostname) {

  top.location.href = window.location.href;

}

但是,出乎意料的是,這樣寫是錯誤的,根本無法執行。你能看出,錯在哪裡嗎?

假定 top.location.hostname 是 www.111.com,而 window.location.hostname 是 www.222.com。也就是說,111.com把222.com嵌入了它的網頁中。這時,比較 top.location.hostname != window.location.hostname 會有什麼結果?

瀏覽器會提示程式碼出錯!

因為它們跨域(cross-domain)了,瀏覽器的安全政策不允許222.com的網頁操作111.com的網頁,反之亦然。IE把這種錯誤叫做"沒有許可權"。進一步說,瀏覽器甚至不允許你檢視top.location.hostname,跨域情況下,一看到這個物件,就直接報錯。

那麼,程式碼應該如何修改?

事實上,這提示我們,只要檢視top.location.hostname是否報錯就可以了。如果報錯了,表明存在跨域,就對top物件進行URL重導向;如果不報錯,表明不存在跨域(或者未使用框架),就不採取操作。

try{

  top.location.hostname;

}

catch(e){

  top.location.href = window.location.href;

}

這樣寫已經正確了,在IE和Firefox中可以正確執行。但是,Chrome瀏覽器會出現錯誤,不知為何,在跨域情況下,Chrome對top.location.hostname不報錯!

沒辦法,只能為了Chrome,再加一段補充程式碼。

try{

  top.location.hostname;

  if (top.location.hostname != window.location.hostname) {

    top.location.href =window.location.href;

  }

}

catch(e){

  top.location.href = window.location.href;

}

好了,升級版程式碼完成。除了本地域名以外,其他域名一律無法將你的網頁嵌入框架。我的Blog現在就使用這段程式碼。

==============================

P.S.

除了程式碼以後,我還有一件事要說。

今年6月5日,在《創業途徑:手工雜誌》一文的最後,我說:

"喜歡手工的女同學們,建議你們試試。只要你的作品有趣,我幫你在我的Blog上推廣。"

結果,真的有女同學找我。Daisy來信說,她和女友做了一本電子雜誌《上班族》,希望我幫忙推廣。

防止網頁被嵌入框架的程式碼(續)

雖然我對上班這件事一點興趣也沒有,也不覺得這種主題值得做,但是我不想食言,而且我一向覺得,追求夢想的人值得鼓勵。所以,歡迎大家閱讀

最後,為了增加點選率,Daisy同學自願提供了一張生活照。

防止網頁被嵌入框架的程式碼(續)

(完)

相關文章