使用 Origin-Agent-Cluster 標頭進行效能隔離

新的 HTTP 回應標頭,可限制全網域指令碼作業,並向瀏覽器要求專屬資源。

Domenic Denicola
Domenic Denicola

Origin-Agent-Cluster 是新的 HTTP 回應標頭,可指示瀏覽器在相同網站的跨來源網頁之間,防止同步指令碼存取。瀏覽器也可能使用 Origin-Agent-Cluster 做為提示,表示來源應取得自己的獨立資源,例如專屬程序。

目前 Origin-Agent-Cluster 標頭只能在 Chrome 88 以上版本中實作。這項設計是與 Mozilla Firefox 代表密切合作而成,他們認為這項設計值得做為原型設計,且 Safari 所使用的瀏覽器引擎 WebKit 代表也對這項設計有初步的正面評價

但在此期間,您可以為所有使用者部署 Origin-Agent-Cluster 標頭。無法解讀的瀏覽器會直接忽略。而且,與網站鍵值 (預設值) 相比,來源鍵值代理程式叢集中的網頁實際上可以執行較少功能,因此不必擔心互通性問題。

瀏覽器無法自動區隔相同網站來源的原因

網路是建立在同源政策之上,這是一項安全性功能,可限制文件和指令碼與其他來源的資源互動的情形。舉例來說,由 https://a.example 代管的網頁與 https://b.example 的某個來源不同,或另一個位於 https://sub.a.example 的網頁。

在幕後,瀏覽器會以不同方式使用來源提供的分隔方式。在過去,即使個別來源無法存取彼此的資料,仍會共用作業系統執行緒、程序和記憶體分配等資源。也就是說,如果一個分頁速度緩慢,其他分頁也會因此變慢。或者,如果一個分頁耗用太多記憶體,可能會導致整個瀏覽器當機。

現今的瀏覽器較為複雜,並且嘗試將不同的來源分成不同的程序。具體運作方式會因瀏覽器而異:大多數瀏覽器的分頁之間都有一定程度的區隔,但單一分頁中的不同 iframe 可能會共用一個程序。此外,程序會耗用些許記憶體負擔,因此會利用經驗法則,避免產生過多的記憶體:例如 Firefox 設有可由使用者設定的程序限制,而 Chrome 的行為則在電腦和行動裝置 (記憶體相當稀少的地方) 不同。

這些推論法並非完美無缺,但這類方法有一個重大限制:由於同源政策有例外狀況,允許 https://sub.a.examplehttps://a.example 等子網域彼此通訊,因此瀏覽器無法自動將子網域與其他子網域區隔開來。

這個預設行為稱為「site-keyed 代理程式叢集」:也就是瀏覽器會根據網站將網頁分組。新的 Origin-Agent-Cluster 標頭會要求瀏覽器變更特定網頁的預設行為,將該網頁放入來源鍵值代理程式叢集,以便只與具有完全相同來源的其他網頁分組。特別是,代理程式叢集會將相同網站的跨來源網頁排除。

這項選擇加入式分隔功能可讓瀏覽器為這些新的 origin-keyed 代理程式叢集提供專屬資源,而不會與其他來源的資源合併。舉例來說,這類網頁可以取得自己的程序,或在不同的執行緒上排程。在網頁中加入 Origin-Agent-Cluster 標頭後,瀏覽器就能知道網頁能善用這類專屬資源。

不過,為了執行分離作業並獲得這些優點,瀏覽器必須停用部分舊版功能。

來源鍵網頁無法執行的操作

當您的網頁位於 origin-keyed 代理程式叢集時,您可以賦予與之前可用的同網站跨來源網頁通訊的功能。請特別注意以下幾點:

  • 您無法再設定 document.domain。這是一項舊版功能,通常會允許同網站跨來源網頁同步存取彼此的 DOM,但在以來源為依據的代理程式叢集中,這項功能會停用。

  • 您無法再透過 postMessage()WebAssembly.Module 物件傳送至其他同網站跨來源頁面。

  • (僅限 Chrome) 無法再傳送 SharedArrayBufferWebAssembly.Memory 物件到其他同網站跨來源頁面。

使用 origin-keyed 代理程式叢集的時機

最能從 Origin-Agent-Cluster 標頭中受益的來源包括:

  • 盡可能使用專屬資源,以獲得最佳效能。例如效能密集型遊戲、視訊會議網站或多媒體創作應用程式。

  • 包含資源密集的 iframe,該 iframe 來自不同來源,但位於同一網站。舉例來說,如果 https://mail.example.com 嵌入 https://chat.example.com iframe,來源鍵 https://mail.example.com/ 可確保聊天團隊編寫的程式碼不會意外干擾郵件團隊編寫的程式碼,並可向瀏覽器提示,讓瀏覽器為這些程式碼提供個別的程序,以便獨立排程,並降低彼此對效能造成的影響。

  • 預期能夠嵌入到不同來源的相同網站頁面,但知道本身需要大量資源。舉例來說,如果 https://customerservicewidget.example.com 預期會使用許多資源進行視訊通訊,並且會在整個 https://*.example.com 中的各種來源嵌入,那麼維護該小工具的團隊可以使用 Origin-Agent-Cluster 標頭,嘗試降低對嵌入器的效能影響。

此外,您也必須確保可以停用上述討論的很少使用的跨來源通訊功能,且您的網站使用 HTTPS

但這些都只是建議,最終決定是否要使用 origin-keyed 代理程式叢集,最好還是透過評估來判斷。您尤其需要評估網站體驗指標以及記憶體用量,瞭解來源鍵功能的影響。(記憶體用量特別值得注意,因為增加執行中的程序數量可能會導致每個程序的記憶體負擔增加)。您不應只推出原始鍵,然後祈禱一切順利。

這與跨來源隔離有何關係?

透過 Origin-Agent-Cluster 標頭為代理程式叢集設定來源鍵,與透過 Cross-Origin-Opener-PolicyCross-Origin-Embedder-Policy 標頭隔離跨來源相關,但兩者是分開的。

任何將自身設為跨來源隔離的網站,也會停用與使用 Origin-Agent-Cluster 標頭相同的同網站跨來源通訊功能。不過,Origin-Agent-Cluster 標頭在跨來源隔離功能之上仍有用處,可做為瀏覽器修改資源分配法則的額外提示。因此,即使是已隔離跨來源的網頁,您仍應考慮套用 Origin-Agent-Cluster 標頭,並評估結果。

如何使用 Origin-Agent-Cluster 標頭

如要使用 Origin-Agent-Cluster 標頭,請設定網路伺服器傳送下列 HTTP 回應標頭:

Origin-Agent-Cluster: ?1

?1 的值是布林值 true結構化標頭語法。

請務必在所有來源回應 (而非部分網頁) 中傳送這個標頭。否則,您可能會得到不一致的結果,因為瀏覽器會「記住」看到原點鍵入要求,因此即使在未要求原點鍵入的網頁上,也會執行原點鍵入。反之,如果使用者造訪的第一個網頁沒有標頭,瀏覽器就會記住您的來源不想使用來源鍵,並忽略後續網頁的標頭。

這個「記憶」的用意在於確保來源的鍵入一致性。如果某個來源的部分網頁已標示來源,而其他網頁則未標示來源,則您可能會有兩個相同來源的網頁,分別放入不同的代理程式叢集,因此無法相互通訊。這對網頁開發人員和瀏覽器內部來說都會很奇怪。因此,如果標頭與先前針對特定來源所見的標頭不一致,Origin-Agent-Cluster 的規格會改為忽略該標頭。在 Chrome 中,這會導致主控台警告。

這項一致性範圍限定為瀏覽內容群組,也就是一組可透過 window.openerframes[0]window.parent 等機制互相連結的分頁、視窗或內嵌框。也就是說,一旦來源的來源或網站鍵入已完成 (瀏覽器已看到或未看到標頭),您就必須開啟全新分頁才能變更,且不得以任何方式連結至舊分頁。

這些詳細資料對於測試 Origin-Agent-Cluster 標頭可能相當重要。首次將其新增至網站時,單純重新載入網頁並無法使用;您必須關閉分頁並開啟新的分頁。

如要檢查是否套用 Origin-Agent-Cluster 標頭,請使用 JavaScript window.originAgentCluster 屬性。如果標頭 (或其他機制,例如 跨來源隔離) 導致來源鍵,則會是 true;如果沒有,則會是 false;如果瀏覽器未實作 Origin-Agent-Cluster 標頭,則會是 undefined。將這項資料記錄到數據分析平台,可提供寶貴的檢查資訊,讓您確認伺服器設定正確無誤。

最後,請注意,Origin-Agent-Cluster 標頭只適用於安全的內容區塊,也就是 HTTPS 網頁或 http://localhost。非 localhost HTTP 網頁不支援來源鍵代理程式叢集。

來源鍵並非安全防護功能

雖然使用 origin-keyed 代理程式叢集確實可將來源與來自同網站跨來源網頁的同步存取隔離,但不會提供 保護,例如 Cross-Origin-Resource-PolicyCross-Origin-Opener-Policy 等安全性相關標頭。尤其是像 Spectre 這類側邊頻道攻擊,並非絕對可靠的防護。

這聽起來有點令人意外,因為來源鍵有時可能會導致來源取得自己的程序,而獨立的程序是抵禦旁路攻擊的重要關鍵。但請注意,Origin-Agent-Cluster 標頭只是相關提示。瀏覽器沒有義務向來源提供獨立程序,且基於各種原因而可能不會進行此程序:

  • 瀏覽器可能不會實作這方面的技術。例如,目前 Safari 和 Firefox 可以將不同的分頁放入各自的程序,但目前還無法針對 iframe 這麼做。

  • 瀏覽器可能會判斷不值得執行獨立程序的負擔。舉例來說,在低記憶體 Android 裝置或 Android WebView 中,Chrome 使用的程序會盡可能少。

  • 瀏覽器可能會遵循 Origin-Agent-Cluster 標頭所指示的要求,但可以使用與程序不同的隔離技術。舉例來說,Chrome 正在研究使用執行緒而非處理程序來進行這類效能隔離。

  • 使用者或在其他網站上執行的程式碼,可能已在您的來源中前往網站鍵入的網頁,導致一致性保證生效,並完全忽略 Origin-Agent-Cluster 標頭。

因此,請勿將來源鍵代理程式叢集視為安全性功能。相反地,這項功能可協助瀏覽器將資源分配優先順序,藉此暗示您的來源可從專屬資源中受益 (且您願意為此放棄特定功能)。

意見回饋

如果您正在使用或考慮使用 Origin-Agent-Cluster 標頭,Chrome 團隊很樂意聽取您的意見。您的興趣和支持有助於我們決定功能的優先順序,並向其他瀏覽器供應商展示這些功能的重要性。請透過推文告訴 @ChromiumDev,讓 Chrome DevRel 瞭解你的想法和體驗。

如果您對規格或功能運作方式的詳細資訊有其他疑問,可以前往 HTML Standard GitHub 存放區提出問題。如果您在實作 Chrome 時遇到任何問題,請前往 new.crbug.com 回報錯誤,並將「元件」欄位設為 Internals>Sandbox>SiteIsolation

瞭解詳情

如要進一步瞭解以來源為索引的代理程式叢集,請參閱下列連結中的詳細資訊: