一、前言
在默認情況下,如果打開一個標簽頁,那么瀏覽器會默認為其創建一個渲染進程。
如果從一個標簽頁中打開了另一個新標簽頁,當新標簽頁和當前標簽頁屬于同一站點(相同協議、相同根域名)的話,那么新標簽頁會復用當前標簽頁的渲染進程。
多個標簽頁運行在同一個渲染進程:從標簽頁中打開新的標簽頁
多個標簽頁運行在不同的渲染進程中:新建一個標簽頁打開
二、標簽頁之間的連接
可以通過 window.opener
操作
1.通過標簽<a>
來和新標簽建立連接
<a href="https://time.geekbang.org/" target="_blank" class="">極客時間</a>
2.通過 window.open
方法來和新標簽頁建立連接
new_window = window.open("http://time.geekbang.org")AI寫代碼js
1
在 WhatWG 規范中,把這一類具有相互連接關系的標簽頁稱為瀏覽上下文組 ( browsing context group)。
一個標簽頁所包含的內容,諸如 window 對象,歷史記錄,滾動條位置等信息稱為瀏覽上下文。通過腳本相互連接起來的瀏覽上下文就是瀏覽上下文組。
規范文檔
Chrome 瀏覽器會將瀏覽上下文組中屬于同一站點的標簽分配到同一個渲染進程中。
為什么它們必須運行在同一渲染進程中?
因為如果一組標簽頁,既在同一個瀏覽上下文組中,又屬于同一站點,那么它們可能需要在對方的標簽頁中執行腳本。
計算標簽頁使用的渲染進程數目:
三、noopener 與 noreferrer
Chrome 瀏覽器為標簽頁分配渲染進程的策略:
- 如果兩個標簽頁都位于同一個瀏覽上下文組,且屬于同一站點,那么這兩個標簽頁會被瀏覽器分配到同一個渲染進程中。
- 如果這兩個條件不能同時滿足,那么這兩個標簽頁會分別使用不同的渲染進程來渲染。
例子:首先打開 linkmarket.aliyun.com
這個標簽頁,再在這個標簽頁中隨便點擊兩個鏈接,然后就打開了兩個新的標簽頁了,如下圖所示:
A、B、C 三個標簽頁都屬于同一站點,正常情況下,它們應該共用同一個渲染進程,不過通過上圖我們可以看出來,A、B、C 三個標簽頁分別使用了三個不同的渲染進程。
說明這三個標簽頁不在同一個瀏覽上下文組中。
怎么驗證?
可以通過控制臺,來看看 B 標簽頁和 C 標簽標簽頁的 opener 的值都是 null,說明 B、C 標簽頁和 A 標簽頁沒有連接關系,不屬于同一瀏覽上下文組。
實現的原理是什么?
鏈接使用了 rel = noopener
:
- noopener:告訴瀏覽器,通過這個鏈接打開的標簽頁中的 opener 值設置為 null
- noreferrer:告訴瀏覽器,新打開的標簽頁不要有引用關系。
阿里為什么要把同一站點的tab簽做成無連接的,會避免什么安全隱患啊?
如果多個標簽在同一個進程中,那么一個標簽淪陷了,其它標簽都會淪陷的
更多可以參考:nofollow、noopener和noreferrer標簽的區別
1.什么是 noreferrer 標簽?
簡而言之,noreferrer 標記在單擊鏈接時隱藏引用者信息。如果有人從使用此標記的鏈接到達您的網站,您的分析將不會顯示誰提到該鏈接。相反,它會錯誤地顯示為您的統計流量報告中的直接流量。
這個 noreferrer 標簽在 WordPress 早些版本中是自動添加到 A 標簽中,但實際上這并不是 WordPress 本身所做的改變,而是由 WordPress 使用的富文本編輯器 TinyMCE(WordPress 默認編輯器)造成的。目的就是防止網絡釣魚攻擊,垃圾郵件發送者劫持您的網頁,可能會訪問您的網站或訪問機密信息。不過現在 TinyMCE 只強制插入 noopener 標簽,已經不會強制插入“noopener noreferrer”標簽。
2.什么是 noopener 標簽?
rel =“noopener” 在新標簽中打開鏈接時基本上不會打開它的開啟者。這意味著,它的 window.opener 屬性將是在新標簽中打開一個鏈接時,而不是從那里的鏈接打開同一個頁面為空。
rel =“noopener” 一般都是搭配 target=“_blank"同時使用,因為 target=”_blank" 也是一個安全漏洞:新的頁面可以通過 window.opener 訪問您的窗口對象,并且它可以使用 window.opener.location = newURL 將您的頁面導航至不同的網址。新頁面將與您的頁面在同一個進程上運行,如果新頁面正在執行開銷極大的 JavaScript,您的頁面性能可能會受影響。
3.什么是 nofollow 標簽?
nofollow 標簽就是告訴百度、Google 等搜索引擎不要通過使用此標記的鏈接傳遞任何值。大多數情況下,nofollow 標簽用于阻止“PageRank”傳遞到網站上的管理頁面(例如,您不需要排名的登錄頁面),或者根據 Google 的付費使用廣告客戶的 URL 鏈接政策。除了用于付費和管理鏈接之外,nofollow 標記通常用于限制 PageRank 通過博客評論或留言簿條目中的鏈接傳遞。在鏈接到信譽或可信度可能成為問題的網站時,您也可以使用 nofollow。
4.noopener 和 noreferrer 標簽如何提高安全性?
noopener 和 noreferrer 標簽是阻止漏洞利用的主動權,該漏洞利用在新標簽中打開的鏈接。很少有成員知道這個漏洞,因此 WordPress 采取這一舉措來提高用戶的安全性。反向 Tabnabbing 是一種網絡釣魚攻擊,攻擊者用惡意文檔替換合法且可信的頁面選項卡。
當有人打開新選項卡時,網絡釣魚者會通過 window.opener 檢測引薦網址,并使用 window.opener.location = newURL 推送新的網址。
這樣,沒有人會有陷入網絡釣魚攻擊的線索,因為他們已經從可靠的來源(WordPress 建立的網站)到達網站。而使用 rel =“noopener”會阻止網絡釣魚者獲取有關鏈接源和與 referrer 鏈接相關的任何數據的信息。
5.nofollow、noopener 和 noreferrer 標簽對SEO 有什么影響?
這是許多博主站長們關心的問題,因為大家都知道 nofollow 標簽會影響 Google 等搜索引擎的抓取和索引鏈接以及傳遞 PageRank 的能力,所以大家都比較擔心 noopener 標簽和 noreferrer 標簽也會這樣做。
其實,noopener 標簽和 noreferrer 標簽對 SEO 沒有任何影響。簡而言之,它們運行在分析/瀏覽器級別,而不是搜索引擎級別。雖然在監控反饋流量方面存在嚴重問題,但它不會影響站點內容的索引、抓取或排名方式。
四、站點隔離
目前 Chrome 瀏覽器已經默認實現了站點隔離的功能,這意味著標簽頁中的 iframe 也會遵守同一站點的分配原則。如果 iframe 和標簽頁不屬于同一站點,那么 iframe 會運行在單獨的渲染進程中。
例子:
<!DOCTYPE html>
<html lang="en">
<head><title>站點隔離:demo</title><style>iframe {width: 800px;height: 300px;}</style>
</head>
<body><div><iframe src="iframe.html"></iframe></div><div><iframe src="https://www.infoq.cn/"></iframe></div><div><iframe src="https://geekbang.org/"></iframe></div><div><iframe src="https://meiqia.com/"></iframe></div>
</body>
</html>
iframe 使用單獨的渲染進程:
計算 iframe 所使用的渲染進程數目:
- InfoQ、極客邦兩個 iframe 與父標簽頁不屬于同一站點,所以它們會被分配到不同的渲染進程中
- iframe.html 和源標簽頁屬于同一站點,所以它會和源標簽頁運行在同一個渲染進程中。
五、總結
首先使用兩種不同的方式打開兩個標簽頁,第一種是從 A 標簽頁中通過鏈接打開了B 標簽頁,第二種是分別打開 A 和 B 標簽頁,這兩種情況下的 A 和 B 都屬于同一站點。
通過 Chrome 的任務管理器我們發現,雖然 A 標簽頁和 B 標簽頁都屬于同一站點,不過通過第一種方式打開的 A 標簽頁和 B 標簽頁會共用同一個渲染進程,而通過第二種方式打開
的兩個標簽頁卻分別使用了兩個不同的渲染進程。
這是因為,使用同一個渲染進程需要滿足兩個條件:首先 A 標簽頁和 B 標簽頁屬于同一站點,其次 A 標簽頁和 B 標簽頁需要有連接關系。
接著,分析了一個“例外”,如果在鏈接中加入了 rel=noopener 屬性,那么通過鏈接打開的新標簽頁和源標簽頁之間就不會建立連接關系了。
最后我們還分析了站點隔離對渲染進程個數的影響,如果 A 標簽頁中的 iframe 和 A 標簽頁屬于同一站點,那么該 iframe 和 A 標簽頁會共用同一個渲染進程,如果不是,則該iframe 會使用單獨的渲染進程。
到了這里相信你已經會計算渲染進程的個數了。在最后我們還要補充下同源策略對同一站點的限制,雖然 Chrome 會讓有連接且屬于同一站點的標簽頁運行在同一個渲染進程中,不過如果 A 標簽頁和 B 標簽頁屬于同一站點,卻不屬于同源站點,那么你依然無法通過 opener 來操作父標簽頁中的 DOM,這依然會受到同源策略的限制。
簡單地講,極客邦和極客時間屬于同一站點,但是他們并不是同源的,因為同源是需要相同域名的,雖然根域geekbang.org 相同,但是域名卻是不相同的,一個是time.geekbang.org,一個是 www.geekbang.org, 因此瀏覽器判斷它們不是同源的,所以依然無法通過 time.geekbang.org 標簽頁中的 opener 來操作 www.geekbang.org 中的 DOM。