本文給大家分享一個關(guān)于 Web 的知識點。假如你做過一段時間Web
開發(fā),那你可能已經(jīng)知道了。但是對于新手還是可以了解一下的。
我們知道,網(wǎng)頁里的a
標簽?zāi)J在當前窗口跳轉(zhuǎn)鏈接地址,如果需要在新窗口打開,需要給 a
標簽添加一個target="_blank"
屬性。
<a href="http://m.hgci.cn/" target="_blank">W3Cschool編程獅</a>
順便提下一個有意思的現(xiàn)象,很早之前我就發(fā)現(xiàn),國外網(wǎng)站傾向于在當前頁跳轉(zhuǎn),而國內(nèi)網(wǎng)站喜歡打開新窗口。不信你們可以去驗證下。我不知道這是交互設(shè)計上的文化差異,還是技術(shù)上的開發(fā)習(xí)慣。
當然,這兩種方式各有優(yōu)缺點。當前頁跳轉(zhuǎn)顯得操作比較有連貫性,不會貿(mào)然打斷用戶的注意力,也會減少瀏覽器的窗口(tab 頁)數(shù)量。但是對于需要反復(fù)回到初始頁面的場景來說,就很麻煩了。比如搜索結(jié)果頁面,通常需要查看對比幾個目標地址,保留在多個窗口還是比較方便。
今天要說的不只是用戶體驗上的差別,而是涉及安全和性能。
安全隱患
如果只是加上target="_blank"
,打開新窗口后,新頁面能通過window.opener
獲取到來源頁面的window
對象,即使跨域也一樣。雖然跨域的頁面對于這個對象的屬性訪問有所限制,但還是有漏網(wǎng)之魚。
這是某網(wǎng)頁打開新窗口的頁面控制臺輸出結(jié)果。可以看到window.opener
的一些屬性,某些屬性的訪問被攔截,是因為跨域安全策略的限制。
即便如此,還是給一些操作留下可乘之機。比如修改window.opener.location
的值,指向另外一個地址。你想想看,剛剛還是在某個網(wǎng)站瀏覽,隨后打開了新窗口,結(jié)果這個新窗口神不知鬼不覺地把原來的網(wǎng)頁地址改了。這個可以用來做什么?釣魚?。〉饶慊氐侥莻€釣魚頁面,已經(jīng)偽裝成登錄頁,你可能就稀里糊涂把賬號密碼輸進去了。
還有一種玩法,如果你處于登錄狀態(tài),有些操作可能只是發(fā)送一個GET
請求就完事了。通過修改地址,就執(zhí)行了非你本意的操作,其實就是 CSRF 攻擊。
性能問題
除了安全隱患外,還有可能造成性能問題。通過target="_blank"
打開的新窗口,跟原來的頁面窗口共用一個進程。如果這個新頁面執(zhí)行了一大堆性能不好的 JavaScript 代碼,占用了大量系統(tǒng)資源,那你原來的頁面也會受到池魚之殃。
解決方案
盡量不使用target="_blank"
,如果一定要用,需要加上rel="noopener"
或者rel="noreferrer"
。這樣新窗口的window.openner
就是null
了,而且會讓新窗口運行在獨立的進程里,不會拖累原來頁面的進程。不過,有些瀏覽器對性能做了優(yōu)化,即使不加這個屬性,新窗口也會在獨立進程打開。不過為了安全考慮,還是加上吧。
我找了個博客網(wǎng)站試了一下,點擊里面的外鏈打開新頁面,window.openner都
是null
。查看頁面元素發(fā)現(xiàn),a
標簽都加上了 rel="noreferrer"。博客是用 Hexo 生成的,看來這種設(shè)置已經(jīng)成了基本常識了。
另外,對于通過window.open
的方式打開的新頁面,可以這樣做:
var yourWindow = window.open();
yourWindow.opener = null;
yourWindow.location = "http://someurl.here";
yourWindow.target = "_blank";
希望這個小技巧對你有用。
以上就是W3Cschool編程獅
關(guān)于 網(wǎng)頁鏈接用了target="_blank",結(jié)果出乎意料 的相關(guān)介紹了,希望對大家有所幫助。