如何建構多個 PWA,並運用相同的網域名稱,讓使用者察覺他們屬於同一個機構或服務。
Demian 在「多來源網站的漸進式網頁應用程式」網誌文章中談到,嘗試建構涵蓋所有來源的單一漸進式網頁應用程式時,網站會面臨哪些挑戰。
以這種網站架構為例,電子商務網站是指:
- 首頁是
https://www.example.com
。 - 類別網頁由
https://category.example.com
代管。 - 位於
https://product.example.com
的產品詳細資料頁面。
如文章所述,相同來源政策設有幾項限制,防止跨來源共用服務工作站、快取和權限。因此,我們強烈建議避免使用這類設定,對於以這種方式建構網站的網站,建議您盡可能考慮遷移至單一來源網站架構。
![這張圖表顯示網站分成多個來源,並說明建構 PWA 時不建議採用的技術。](https://web.developers.google.cn/static/articles/building-multiple-pwas-on-the-same-domain/image/diagram-showing-site-div-64e98fc6031ee.png?authuser=19&hl=zh-tw)
在這篇文章中,我們將做出相反的情況:我們會分析想要提供多個 PWA 的公司、利用同一個網域名稱,並讓使用者瞭解這些 PWA 屬於同一個機構或服務,而不是從不同來源選取單一 PWA。
您可能已經發現,我們使用的是不同但相關的字詞,例如網域和來源。在繼續之前,讓我們先複習一下這些概念。
相關術語
- 網域:網域名稱系統 (DNS) 中定義的任何一串標籤順序。
舉例來說,
com
和example.com
都是網域。 - 主機名稱:這類 DNS 項目至少會解析為一個 IP 位址。舉例來說,
www.example.com
將是主機名稱,如果example.com
有 IP 位址,就會是主機名稱,而com
永遠不會解析為 IP 位址,所以它就不能是主機名稱。 - 來源:配置、主機名稱和 (選擇性) 通訊埠的組合。舉例來說,
https://www.example.com:443
就是來源。
顧名思義,相同來源政策對來源設有限制,因此我們在整篇文章中大部分都提及字詞。然而,為了建立不同的「來源」,我們會不時使用「網域」或「子網域」來描述目前使用的技巧。
多個相關 PWA 的情況
在某些情況下,您可能想要建構獨立的應用程式,但仍可將其識別為同一個機構或「品牌」所有。重複使用相同的網域名稱是建立關係的好方法。例如:
- 電子商務網站想要建立獨立的體驗,讓賣家管理商品目錄,同時確保他們瞭解該網站屬於使用者購買產品的主要網站。
- 某個運動新聞網站想為重大體育賽事建構特定應用程式,讓使用者能夠透過通知接收喜愛比賽的統計資料,並且安裝為漸進式網頁應用程式,同時確保使用者將其視為新聞公司建構的應用程式。
- 某間公司想要建構個別的即時通訊、郵件和日曆應用程式,並希望這些應用程式能以與公司名稱連結的個別應用程式的形式運作。
![嘗試建立統一的正規化網頁應用程式時,請避免在相同網站的各部分使用不同的來源。](https://web.developers.google.cn/static/articles/building-multiple-pwas-on-the-same-domain/image/avoid-using-different-ori-d78df43acb88b.png?authuser=19&hl=zh-tw)
使用不同的來源
針對這類情況,建議採取的做法是將每個概念明確的應用程式都放在自己的來源上。
如要在所有網域中使用相同的網域名稱,可以使用子網域。舉例來說,提供多個網際網路應用程式或服務的公司可在 https://mail.example.com
代管郵件應用程式,以及使用 https://calendar.example.com
代管日曆應用程式,同時提供 https://www.example.com
公司的主要服務。另一個例子是運動網站,目的是為重要運動活動 (例如 https://footballcup.example.com
的足球錦標賽) 建立完全專用的獨立應用程式,讓使用者可以獨立安裝及使用,而不需要由 https://www.example.com
代管的主要運動網站。如果平台可讓客戶根據公司品牌自行建立獨立應用程式,這個方法也很實用。例如,可讓商家在 https://merchant1.example.com
、https://merchant2.example.com
等位置建立自己的 PWA 的應用程式。
使用不同來源可確保應用程式之間能夠區隔開來,意味著每個應用程式都能獨立管理不同的瀏覽器功能,包括:
- 可安裝性:每個應用程式都有專屬的資訊清單,並提供專屬的安裝體驗。
- 儲存空間:每個應用程式都有專屬的快取、本機儲存空間,以及幾乎所有形式的裝置本機儲存空間,不會與他人分享。
- 服務工作站:每個應用程式都有專屬的已註冊範圍的 Service Worker。
- 權限:權限也會依來源設定範圍。有鑑於此,使用者能確切知道他們授予了哪些服務的權限,而通知之類的功能則會正確歸因至各個應用程式。
針對多個獨立的 PWA 用途,建立這種隔離程度最為理想,因此強烈建議這種做法。
如果子網域上的應用程式想要彼此共用本機資料,仍能使用 Cookie 進行共用;或者,若是更進階的情況,則可考慮透過伺服器同步處理儲存空間。
![ALT_TEXT_HERE](https://web.developers.google.cn/static/articles/building-multiple-pwas-on-the-same-domain/image/alttexthere-699ea17734325.png?authuser=19&hl=zh-tw)
使用相同的來源
第二種做法是在相同來源上建構不同的 PWA。這包括以下情境:
非重疊路徑
多個 PWA 或概念式「網頁應用程式」,由同一來源代管,且路徑不會重疊。例如:
https://example.com/app1/
https://example.com/app2/
重疊/巢狀路徑
在同一來源上有多個 PWA,其中一個 PWA 以巢狀結構內嵌:
https://example.com/
(「外部應用程式」)https://example.com/app/
(「內部應用程式」)
Service Worker API 和資訊清單格式可讓您使用路徑層級的範圍,執行上述任一操作。然而,在這兩種情況下,使用相同來源都會帶來許多問題和限制,根源是因為瀏覽器不會將其完全視為不同的「應用程式」,因此我們不建議採取這種做法。
![ALT_TEXT_HERE](https://web.developers.google.cn/static/articles/building-multiple-pwas-on-the-same-domain/image/alttexthere-67b559ff24375.png?authuser=19&hl=zh-tw)
在下一節中,我們會進一步分析這些挑戰,以及如果無法使用獨立來源時可解決哪些問題。
多個相同來源 PWA 面臨的挑戰
以下是這兩種方法常見的實際問題:
- 儲存空間:Cookie、本機儲存空間和所有形式的裝置本機儲存空間都是在應用程式之間共用。因此,如果使用者決定抹除某個應用程式的本機資料,就會抹除來源中的所有資料。單一應用程式無法執行這項操作。請注意,Chrome 和部分其他瀏覽器會在解除安裝其中一個應用程式時,主動提示使用者清除本機資料,而這也會影響來源上其他應用程式的資料。另一個問題是應用程式也必須共用儲存空間配額,也就是說,如果任一應用程式佔用過多空間,另一個問題就會對另一個應用程式造成負面影響。
- 權限:權限與來源有關。也就是說,如果使用者對某個應用程式授予權限,則系統會同時將權限套用至該來源上的所有應用程式。這聽起來或許是個好事 (不必多次要求權限),但請記住:如果使用者封鎖某個應用程式的權限,其他應用程式就無法要求該項權限或使用該項功能。
- 使用者設定:系統也會按照來源進行設定。舉例來說,假設兩個應用程式的字型大小不同,且使用者想只為了補償畫面調整縮放比例,則如果沒有將這項設定套用至其他應用程式,也就無法這麼做。
這些挑戰使我們很難鼓勵這種策略。不過,如我們在「使用個別來源」一節所述,無法使用獨立的來源 (例如子網域),您可以從我們提供的兩個相同來源選項中使用非重疊路徑,強烈建議使用重疊/巢狀路徑。
如先前所述,本節討論的挑戰在相同來源方法中都很常見。下一節將詳細說明最不推薦使用重疊/巢狀路徑的原因。
重疊/巢狀路徑的額外挑戰
重疊/巢狀路徑方法 (https://example.com/
為外部應用程式,https://example.com/app/
為內部應用程式) 的另一個問題是,系統實際上會將內部應用程式中的所有網址,視為外部應用程式和內部應用程式的一部分。
實務上來說,這帶來下列問題:
- 安裝促銷活動:如果使用者造訪內部應用程式 (例如透過網路瀏覽器),則如果外部應用程式已經安裝在使用者的裝置上,瀏覽器就不會顯示安裝宣傳橫幅,也不會觸發 BeforeInstallPrompt 事件。這是因為瀏覽器會檢查目前的頁面是否屬於已安裝的應用程式,然後判斷出該頁面就是已安裝的應用程式。解決方法是手動安裝內部應用程式 (透過「建立捷徑」瀏覽器選單選項),或先安裝內部應用程式,再使用外部應用程式。
- 通知和 Badging API:如果外部應用程式已安裝,但內部應用程式未安裝,則來自內部應用程式的通知和標記會錯誤歸因於外部應用程式 (即已安裝應用程式的最底端應用程式範圍)。如果使用者在裝置上安裝兩個應用程式,這項功能就能正常運作。
- 連結擷取:外部應用程式可能會擷取屬於內部應用程式的網址,尤其可能在已安裝外部應用程式,但未安裝內部應用程式的情況下。同樣地,外部應用程式中連結到內部應用程式的連結,也不會將擷取資料連結至內部應用程式,因為這類連結會被視為外部應用程式的範圍內。此外,在 ChromeOS 和 Android 上,如果這些應用程式已加入 Play 商店 (做為可信任的網路活動),外部應用程式就會擷取所有連結。即使已安裝內部應用程式,OS 仍可讓使用者選擇要在外部應用程式中開啟這些應用程式。
結論
在這篇文章中,我們介紹了開發人員以不同方式,在相同網域中建構多個彼此相關的漸進式網頁應用程式。
總而言之,我們強烈建議使用不同來源 (例如使用子網域) 代管獨立的 PWA。在同一來源託管這些容器會帶來許多挑戰,主要原因是因為瀏覽器不將這些應用程式視為不同的應用程式。
- 不同來源:建議
- 相同來源且不重疊的路徑:不建議採用
- 相同來源,重疊/巢狀路徑:不建議使用
如果無法使用不同的來源,請使用非重疊的路徑 (例如 https://example.com/app1/
和 https://example.com/app2/
),我們強烈建議不要使用重疊或巢狀路徑,例如 https://example.com/
(針對外部應用程式) 和 https://example.com/app/
(適用於內部應用程式)。
其他資源
由衷感謝提供技術評論和建議:Joe Medley、Dominick Ng、Alan Cutter、Daniel Murphy、Penny McLachlan、Thomas Steiner 和 Darwin Huang
相片來源:Tim Mossholder 放在 Unsplash 網站上