題幹與適用場景
一個 Service Worker 需要只攔截同源的圖片和文件路由,並擷取租戶與資源 ID。請用 URLPattern 設計匹配器,說明元件邊界、擷取組、大小寫和不支援瀏覽器的降級。
URLPattern 提供標準化的 URL 模式匹配器,能分別匹配協定、主機、連接埠、路徑、查詢和片段,並回傳命名或編號擷取組。它適合路由分派、Service Worker 快取和邊緣規則,但匹配成功不等於權限通過,也不能取代正規化與授權檢查。
面試官考察點
重點包括:按 URL 元件而不是整串文字匹配、萬用字元與分組語法、相對模式的 baseURL、各元件預設大小寫規則、擷取結果的可信邊界,以及跨瀏覽器相容和模式編譯失敗處理。
澄清問題
先確認只允許哪些協定、主機和連接埠,路徑是否區分大小寫,查詢參數是否參與匹配,以及租戶和資源 ID 是否必須完整匹配。再確認執行在頁面、Service Worker 還是 Worker,目標瀏覽器支援範圍,以及匹配結果是否會影響快取或安全決策。
30 秒回答框架
「我會把協定、主機和連接埠寫成固定元件,只在路徑中使用命名擷取組提取租戶和資源 ID,並用 baseURL 明確相對模式的解析基準。模式編譯時立即捕獲語法錯誤,執行時先檢查完整 URL 和同源約束,再使用結果驅動快取或路由。URLPattern 只是匹配器,不提供授權;不支援的瀏覽器使用 URL 解析加上經過測試的有限回退,避免用正則複製完整 URL 語義。」
分步驟深入解答
第一步:按元件建構模式
URLPattern 可以接收包含 protocol、hostname、port、pathname、search 和 hash 的物件,也可以接收 URL 風格字串。安全敏感的路由應明確協定和主機,不要只匹配路徑後接受任意來源。
第二步:使用命名擷取組
路徑中的命名組可以從 exec() 結果讀取,便於把租戶和資源 ID 映射到業務欄位。擷取組只說明字串符合模式,仍需檢查字元集、長度和業務存在性。
const assetPattern = new URLPattern({
protocol: "https",
hostname: "cdn.example.com",
pathname: "/tenant/:tenantId/assets/:assetId.:ext",
});
const match = assetPattern.exec(request.url);
const assetId = match?.pathname.groups.assetId;第三步:明確萬用字元與分隔邊界
萬用字元匹配的是特定元件中的字元,不應假設它會跨越路徑分隔符或自動涵蓋查詢。需要匹配層級時明確寫出每一段,並測試空值、額外斜線和編碼字元。
第四步:理解 baseURL 與相對模式
相對模式需要 baseURL 才能確定協定、主機等元件。不同環境使用不同 baseURL 會得到不同匹配器,因此應把基準 URL 固定在建構處,並在測試中涵蓋開發、預覽和生產網域。
第五步:處理大小寫與正規化
各 URL 元件的大小寫規則並不相同;主機名稱通常按不區分大小寫處理,而路徑等元件可能區分大小寫。不要先把整條 URL 統一轉小寫,否則可能改變資源路徑或簽名輸入。
第六步:把匹配與授權分開
URLPattern 不驗證租戶是否屬於目前使用者,也不檢查資源是否可讀。匹配後仍需執行同源、認證、授權、快取隔離和回應內容型別檢查,尤其不能把擷取的租戶 ID 當作可信身份。
第七步:編譯錯誤與執行期效能
模式在建構時解析;非法語法應在啟動或註冊階段失敗,而不是等請求到來才發現。重用已編譯實例,避免每個請求重新建構;高流量路徑仍需透過真實 URL 分布測量匹配成本。
第八步:設計相容回退
不支援 URLPattern 的環境可以使用 new URL() 逐元件檢查,但只實作業務實際需要的有限模式。不要用一個寬泛正則複製協定、主機、編碼和查詢解析;回退邏輯必須與原生匹配器共享同一組用例。
高品質示例答案
我會建構固定 https、固定 CDN 主機和明確路徑元件的 URLPattern,用命名組擷取租戶與資源 ID。Service Worker 收到請求後先執行完整 URL 匹配,再檢查同源、認證和快取分區;擷取結果只當作未驗證字串,繼續做長度、字元集和資源權限檢查。模式在初始化時編譯並捕獲語法錯誤,實例在請求間重用。相對模式的 baseURL 固定為部署網域,測試涵蓋大小寫、編碼斜線、額外查詢和不同環境。舊瀏覽器使用 URL 的有限逐元件回退,禁止用寬泛正則取代完整 URL 語義。
常見誤區
只匹配 pathname 就認為請求同源
任意協定或主機都可能通過同一路徑。安全敏感匹配器必須固定來源元件,並在執行時再次檢查請求來源。
把擷取組當作已驗證 ID
擷取組只證明形狀匹配。仍需驗證字元集、長度、租戶歸屬、資源存在性和存取權限。
用小寫化或正則簡化所有 URL
元件大小寫和編碼語義不同。整串小寫可能破壞路徑和簽名,寬泛正則也容易跨越分隔符或遺漏查詢規則。
延伸追問與參考答案
如何避免開發網域的 baseURL 洩漏到生產?
把 baseURL 作為部署設定在初始化時注入,啟動時驗證允許的協定和主機,並在建置與端到端測試中固定生產網域。不要從使用者可控 URL 推導安全匹配器的基準。
模式需要支援可選副檔名怎麼辦?
用規範允許的可選分組表達,並分別測試有副檔名、無副檔名、額外點號和編碼字元。擷取結果為空時仍要選擇明確的內容型別和快取策略。
URLPattern 與路由函式庫如何共存?
讓 URLPattern 負責邊緣或 Service Worker 的快速篩選,讓應用路由函式庫負責完整導覽和參數驗證。兩者共享一組 URL 契約測試,避免同一路徑在不同層得到不同解釋。