多來源網站的漸進式網頁應用程式

在多來源網站上建立漸進式網頁應用程式時遇到的挑戰和解決方法。

德米安 (Demián Renzulli)
Demián Renzulli

背景

過去,使用多來源架構可有一些優點,但對漸進式網頁應用程式來說,這種做法可帶來許多挑戰。具體來說,同源政策對服務工作處理程序、快取和權限等內容的共用行為設有限制,以及在多個來源提供獨立體驗時,會受到相關限制。本文將說明多個來源的優缺點,也會說明在多來源網站上建構漸進式網頁應用程式時遇到的挑戰和解決方法。

使用多個來源的良好和不當用途

基於正當理由,網站可能會採用多來源架構,而這些原因多半是為了提供一組獨立的網頁應用程式,或打造彼此完全獨立的體驗。您也應避免使用。

優良範例

以下先來看實用原因:

  • 本地化/語言:使用國家/地區代碼頂層網域,在不同國家/地區 (例如 https://www.google.com.ar) 區隔網站,或使用子網域區隔指定不同地區的網站 (例如https://newyork.craigslist.org) 或提供特定語言的內容 (例如:https://en.wikipedia.org)。

  • 獨立的網頁應用程式:使用不同的子網域提供與主要來源網站明顯有差異的使用體驗。舉例來說,在新聞網站中,填字應用程式可刻意透過 https://crosswords.example.com 提供,並做為獨立的 PWA 進行安裝,同時做為獨立的 PWA,而不需要與主要網站分享任何資源或功能。

壞蛋

如果您沒有執行上述任何動作,那麼在建構漸進式網頁應用程式時,使用多來源架構可能會是缺點。

儘管如此,許多網站仍基於任何特定原因或「舊版」原因繼續採用這種做法。例如使用子網域任意區隔網站中應屬於統一體驗的部分。

舉例來說,強烈建議不要採用下列模式:

  • 網站區塊:根據子網域區分網站的不同區塊。新聞網站經常會出現首頁:https://www.example.com,體育版則位於 https://sports.example.com,政治部分則位於 https://politics.example.com 等。如果是電子商務網站,則使用 https://category.example.com 代表產品類別、使用 https://product.example.com 代表產品網頁等等。

  • 使用者流程:另一種不建議的做法,是將網站中較小的部分分開,例如用於登入頁面或在子網域中的購買流程。例如,使用 https://login.example.comhttps://checkout.example.com

如果無法遷移至單一來源,請參考以下的挑戰清單,以及 (如果可能) 是建構漸進式網頁應用程式時可以考慮的解決方法。

PWA 在不同來源下的挑戰與解決方法

在多個來源建構網站時,提供統合的 PWA 體驗並不容易,多半是因為相同來源政策,具有多項限制。逐一檢查。

Service Worker

Service Worker 指令碼網址的來源必須與呼叫 register() 的網頁來源相同。也就是說,位於 https://www.example.com 的網頁無法使用 Service Worker 網址 (https://section.example.com) 呼叫 register()

另一個考量事項是,服務工作處理程序只能控制由其所屬的來源和路徑所代管的網頁。也就是說,如果 Service Worker 是由 https://www.example.com 代管,就只能控制來自該來源的網址 (根據範圍參數中定義的路徑),但無法控制其他子網域 (例如 https://section.example.com 中的網頁) 中的任何網頁。

在這種情況下,唯一的解決方法是使用多個 Service Worker (每個來源一個)。

快取

Cache 物件、索引資料庫和 localStorage 也受限於單一來源。這表示您無法從 https://www.section.example.com 存取屬於 https://www.example.com 的快取。

在這類情況下,您可以採用以下方式妥善管理快取:

  • 運用瀏覽器快取功能:建議您一律採用傳統的瀏覽器快取最佳做法。這項技術可跨來源重複使用快取資源,這是透過 Service Worker 的快取所無法完成的。如要瞭解如何透過 Service Worker 使用 HTTP 快取,請參閱這篇文章

  • 讓服務工作人員輕鬆進行安裝:如果您維護多個 Service Worker,請避免在使用者每次前往新來源時支付一筆高額的安裝費用。換句話說,請只預先快取確實必要的資源。

權限

權限的範圍也限定於來源,這表示當使用者授予來源 https://section.example.com 的指定權限時,該權限並不會沿用至其他來源,例如 https://www.example.com

由於無法跨來源共用權限,唯一解決方法是只針對需要使用特定功能 (例如位置資訊) 的每個子網域要求權限。對於網頁推送這類操作,您可以保留 Cookie 來追蹤其他子網域的使用者是否接受權限,避免再次要求相同的權限。

安裝

如要安裝 PWA,每個來源都必須具備專屬資訊清單,且該資訊清單具有相對start_url。也就是說,使用者在特定來源 (例如:https://section.example.com) 收到安裝提示時,無法在其他來源 (例如:https://www.example.com) 上安裝 start_url 的 PWA。也就是說,在子網域收到安裝提示的使用者只能為子頁面安裝 PWA,無法安裝應用程式主網址的 PWA。

此外,如果每個子網域都符合安裝條件,系統也會在使用者瀏覽網站時收到多個安裝提示,並提示使用者安裝 PWA。

為緩解這個問題,您可以確保提示只會顯示在主要來源上。當使用者造訪符合安裝條件的子網域時:

  1. 監聽 beforeinstallprompt 事件
  2. 防止顯示提示,呼叫 event.preventDefault()

如此一來,即可確保提示不會顯示在網站的非預期位置,但仍可繼續在主要來源 (例如首頁) 中顯示該提示。

獨立模式

在獨立視窗中進行瀏覽時,當使用者移出 PWA 資訊清單所設的範圍時,瀏覽器的行為會有所不同。(實際做法取決於各個瀏覽器版本和供應商)。舉例來說,如果使用者在獨立模式下移出範圍,最新的 Chrome 版本會開啟 Chrome 自訂分頁

在大多數情況下,我們無法提供解決方案,但可採取替代方案,例如登入工作流程的一小部分服務 (例如登入工作流程):

  1. 新網址 https://login.example.com 可在全螢幕 iframe 中開啟。
  2. 在 iframe 中完成工作 (例如登入程序) 後,即可使用 postMessage(),將 iframe 的任何結果資訊傳回上層頁面。
  3. 最後一個步驟是,當主頁面收到訊息後,即可取消註冊監聽器,且 iframe 最終會從 DOM 中移除。

結語

針對以多個來源為基礎建立的網站,為了提供一致的 PWA 體驗,同源政策施加許多限制。因此,為了提供最佳使用者體驗,我們強烈建議您不要將網站分成不同的來源。

對於以這種方式建構的現有網站,要確保多來源 PWA 正常運作並不容易,但我們已經嘗試了一些可能的解決方法。這兩種方法各有優缺點,因此請自行判斷要為網站採取哪種做法。

評估長期策略或網站重新設計時,除非有必須保留多來源架構的重要理由,否則請考慮遷移至單一來源。

感謝提供技術評論和建議:Penny Mclachlan、Paul Covell、Dominick Ng、Alberto Medina、Pete LePage、Joe Medley、Chney Tsai、Martin Schierle 和 Andre Bandarra。