使用 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.examplehttps://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 代理程式叢集,最好還是透過評估來判斷。特別是,您應該評估 Web Vitals,並可能評估記憶體用量,以瞭解來源鍵值的影響。(記憶體用量特別值得注意,因為增加執行中的程序數量,可能會導致每個程序的記憶體負擔增加)。您不應只推出原始鍵,然後祈禱一切順利。

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

透過 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 回報錯誤,並將「Components」欄位設為 Internals>Sandbox>SiteIsolation

瞭解詳情

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