跳至主要內容

自訂 Captive Portal:HTML 與 CSS 指南

本權威技術參考指南概述了設計和編寫自訂 Captive Portal 登入頁面所需的開發標準、CSS 架構和網路層級限制。它為前端開發人員和網路架構師提供了實用的策略,以應對 Apple CNA 和 Android webview 環境,確保提供像素級完美、合規且高效能的訪客 WiFi 體驗。

📖 11 分鐘閱讀📝 2,731 字數🔧 2 範例3 練習題📚 8 關鍵定義

收聽此指南

查看播客逐字稿
自訂 Captive Portal:HTML 與 CSS 指南 — Purple 技術簡報 [引言] 歡迎收看 Purple 技術簡報系列。今天我們將深入探討影響每個訪客 WiFi 部署的細節 — Captive Portal。具體來說,我們將討論如何為自訂 Captive Portal 登入頁面編寫乾淨、可靠的 HTML 和 CSS。 如果您曾經連接到酒店 WiFi,卻看到一個破裂的登入頁面 — 缺少圖片、未套用樣式的文字、對觸控沒有反應的登入按鈕 — 您就體驗過當開發人員在不了解其運作環境限制的情況下建置 portal 時會發生什麼事。今天,我們將確保這種情況不會發生在您身上。 本簡報針對前端開發人員、創意設計師和網頁開發人員,無論您是從頭開始建置 Captive Portal,還是自訂現有範本。我們將涵蓋 HTML 結構、重要的 CSS 規則、讓即使是有經驗的開發人員也感到棘手的 Apple CNA 微型瀏覽器限制,以及像 Purple 的 portal 產生器這樣的平台如何完全消除大部分的複雜性。 讓我們開始吧。 [技術深挖] 首先,讓我們在網路層級確立 Captive Portal 究竟是什麼。當裝置連接到需要驗證的 WiFi 網路時,網路會攔截 HTTP 流量並將使用者重新導向到登入頁面。這就是 Captive Portal。使用者會看到一個登入頁面,完成一項操作 — 輸入電子郵件、接受條款、透過社群媒體登入 — 然後網路就會授予完整的網際網路存取權限。 需要理解的關鍵是這個頁面是在哪裡渲染的。在 iOS 裝置上,它會在 Apple 的 Captive Network Assistant(即 CNA)中開啟,這是一個精簡版的 WebKit webview。它不是 Safari。它沒有持久性 Cookie。它無法載入外部資源。它的 JavaScript 支援有限。而且在使用者切換到另一個應用程式的瞬間,它就會關閉。在 macOS 上,CNA 以固定的 900 x 572 像素進行渲染。在 Android 上,現代裝置使用 Chrome Custom Tabs,其功能要強大得多。Windows 10 會開啟使用者的預設瀏覽器。Samsung 裝置則使用 Samsung Internet。 這種平台碎片化是生產環境中 Captive Portal 破裂的最大單一原因。開發人員在他們的 Android 手機上進行測試,一切看起來都很棒,然後酒店裡拿著 iPhone 的訪客卻看到一個帶有未套用樣式文字的空白畫面。因此,讓我們來談談如何進行防禦性編碼。 Captive Portal HTML 和 CSS 的黃金法則就是:將頁面視為沒有網際網路連線。因為在驗證階段,它確實沒有。網路是處於 captive 狀態的。您的頁面嘗試從外部 URL 載入的任何資源 — Google Font、CDN 託管的樣式表、JavaScript 程式庫、標誌圖片 — 都會靜默失敗,或導致載入圖示無限旋轉。 從 HTML 結構開始。您的文件應該是一個乾淨的 HTML5 頁面。在 head 中,您需要一個 viewport meta 標籤,其內容設定為 width 等於 device-width 且 initial-scale 等於 1。這對於行動裝置渲染是不可妥協的。如果沒有它,iOS 將以 980 像素寬度渲染頁面並將其縮小,使所有內容都變得極小。 您的 CSS 必須是內聯的 — 可以是 head 元素內 style 區塊中的樣式,也可以是個別元素上的內聯樣式屬性。請勿使用透過 link 標籤連結的外部樣式表。該樣式表存在於您的伺服器上,而 captive 網路在驗證期間無法存取該伺服器。頁面將會完全未套用樣式地渲染。 對於字型,請使用系統字型堆疊。例如:font-family — apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif。這會告訴瀏覽器使用任何可用的系統字型。請勿使用 Google Fonts。import 呼叫將會失敗,而您的備用字型將會是 Times New Roman,這並不是您的客戶付費想要獲得的品牌體驗。 對於圖片 — 您的標誌、背景圖形、裝飾元素 — 您有兩個選擇。要麼從同一個 Captive Portal 伺服器提供服務,這意味著它們位於同一個本地網路中,並且在驗證完成之前即可存取。或者,更好的方法是將它們作為 Base64 資料 URI 直接編碼在您的 HTML 或 CSS 中。這完全消除了外部依賴性。 現在讓我們來談談頁面版面配置。由於超過 90% 的 Captive Portal 登入發生在行動裝置上,您的設計應該是行動優先的。這意味著單欄版面配置,最大寬度約為 480 像素,並在頁面中置中。在 body 元素上使用 flexbox — display flex、flex-direction column、align-items centre、justify-content centre、min-height 100 viewport height。這會將您的內容卡片在任何螢幕尺寸上垂直和水平置中。 您的主要呼叫動作(CTA)按鈕需要易於觸控。Apple 的《人機介面指南》指定最小點按目標為 44 x 44 像素。在實踐中,對於主要 CTA,您會希望高度約為 48 像素,在容器內寬度全滿,邊框半徑(border-radius)約為 8 到 12 像素。 對於表單欄位 — 電子郵件輸入、姓名輸入 — 請將 font-size 設定為至少 16 像素。這至關重要。iOS Safari 和 CNA 會自動放大任何 font-size 低於 16 像素的輸入欄位,這會破壞您精心設計的版面配置。將 font-size 設定為 16 像素或以上可防止這種縮放行為。 法律同意部分值得特別注意。在 GDPR 規範下,如果您正在收集個人資料 — 即使只是電子郵件地址 — 您也需要明確、知情的同意。這意味著一個預設未勾選的核取方塊,並帶有清晰說明使用者同意內容的可見標籤。請勿預先勾選核取方塊。同意核取方塊本身必須清晰可見,無需捲動。 現在,特別針對 iOS CNA 的一個關鍵實作細節。當使用者完成驗證時,CNA 會監控 captive 網域是否已變得可存取。該檢查是由全頁導覽觸發的,而不是由 JavaScript AJAX 呼叫觸發。這意味著,如果您建置了一個單頁應用程式(SPA),該程式透過 fetch 或 XMLHttpRequest 提交表單,並在沒有全頁重新導向的情況下更新 DOM,則 CNA 將永遠無法偵測到驗證已完成。您必須在驗證後重新導向到新的 URL — 執行完整的 HTTP 重新導向,而不是 JavaScript DOM 操作。這是 Captive Portal 開發中最常見的錯誤之一。 對於 JavaScript,請保持極簡。CNA 的 JS 支援有限,且無法存取 localStorage 或 sessionStorage。當 CNA 關閉時,Cookie 會被銷毀。任何依賴這些瀏覽器 API 的狀態管理都將失敗。原生的 JavaScript 事件接聽程式是可以的。jQuery 是一個 30 KB 的外部依賴項,將會載入失敗。 [實作建議與陷阱] 讓我給您實用的實作清單。第一:務必使用 viewport meta 標籤。第二:所有 CSS 內聯,不使用外部樣式表。第三:所有圖片要麼由 Captive Portal 伺服器提供,要麼進行 Base64 編碼。第四:系統字型堆疊,不使用網路字型。第五:所有輸入欄位字型大小至少 16 像素。第六:易於觸控的點按目標,至少 44 x 44 像素。第七:單欄版面配置,最大寬度 480 像素。第八:驗證時進行全頁重新導向,而不是 JavaScript 狀態更新。第九:符合 GDPR 規範的同意核取方塊,預設未勾選。第十:在實際的 captive 網路上使用真實的 iOS 裝置進行測試,而不是瀏覽器預覽。 我在生產環境中最常看到的陷阱。第一:Google Fonts — 移除 import,它會失敗。第二:外部 JavaScript 程式庫 — Bootstrap、jQuery,任何 CDN 託管的指令碼都會失敗。第三:在外部樣式表中宣告的 CSS 變數 — 它們必須在您的內聯樣式區塊中。第四:透過 URL 參照的背景圖片 — 請對其進行 Base64 編碼。第五:沒有驗證後重新導向的 AJAX 表單提交 — CNA 將無法偵測到驗證完成。 現在,讓我們坦誠地談談自建與購買的對比。從頭開始建置自訂 Captive Portal 意味著您還必須負責後端基礎設施 — RADIUS 伺服器、資料庫、SSL 憑證、DNS 設定、與存取點的網路整合以及持續的安全修補。這是一項重大的工程投入。 Purple 的 portal 產生器為需要像素級完美控制的開發人員提供了一個拖放介面以及自訂 HTML 和 CSS 編輯器,同時處理所有後端基礎設施 — 驗證、資料收集、分析、GDPR 合規工具,以及與 200 多家存取點廠商的網路整合。您可以在沒有基礎設施開銷的情況下獲得創意控制權。 [快速問答] 我可以在 Captive Portal 中使用 CSS Grid 嗎?可以,但請特別在 iOS CNA 上進行測試。Flexbox 在較舊的 WebKit 版本中具有更廣泛的支援。我可以使用 SVG 標誌嗎?可以,內聯 SVG 得到完全支援,且對於標誌而言,比 Base64 編碼的 PNG 更佳,因為它們在 Retina 顯示器上能完美縮放。macOS CNA 是否支援與 iOS CNA 相同的限制?大致相同,只有一個區別:macOS CNA 在固定的 900 x 572 像素視窗中渲染。我可以使用像 Tailwind 這樣的 CSS 框架嗎?只有在您產生一個經過清除(purged)、自包含的 CSS 檔案並將其內聯到您的樣式區塊中時才可以。那 HTTPS 呢?您的 Captive Portal 必須透過 HTTP 提供服務,初始重新導向才能運作 — HTTPS 連線無法被 captive 網路攔截。 [總結與後續步驟] 總結今天的簡報。自訂 Captive Portal 是一個受限的網頁環境,而不是標準的瀏覽器環境。Apple CNA 和 Android webview 對外部資源、Cookie、JavaScript 和工作階段狀態施加了嚴格的限制。解決方案是建置自包含的 HTML 頁面,其中包含內聯 CSS、系統字型、Base64 編碼的圖片,並在驗證時進行全頁重新導向。 對於評估其選擇的場地營運商 and IT 團隊:如果您的需求是具有自訂 HTML 和 CSS 的完全品牌化、量身定制的 portal,那麼您需要在自行建置和維護完整堆疊(這是一項重大的工程投入)與使用像 Purple 這樣在生產級後端基礎設施之上提供自訂 HTML 和 CSS 編輯功能的平台之間做出選擇。 接下來的步驟:審查 Purple 的 portal 編輯器文件,根據我們今天涵蓋的行動優先清單稽核您現有的 portal,如果您是從頭開始,請使用我們概述的 HTML 範本結構作為您的基準。感謝您的收聽,我們下期簡報再見。

📚 核心系列的一部分:Captive Portal 終極指南

header_image.png

執行摘要

對於企業場地 — 從奢華酒店 Hospitality 和連鎖零售商 Retail 到交通樞紐 Transport 和現代醫療園區 Healthcare — 訪客 WiFi 登入頁面是數位門面。然而,超過 90% 的訪客 WiFi 登入發生在行動裝置上,其渲染並非由 Safari 或 Chrome 等標準瀏覽器控制,而是由高度受限的 Captive Network Assistant (CNA) webview 控制 [1]。這些「微型瀏覽器」執行嚴格的沙箱限制:它們封鎖外部 CDN、停用持久性 Cookie、忽略外部網路字型,並嚴格限制 JavaScript 執行,以降低安全風險並防止工作階段綁架 [2]。

當開發人員使用傳統網頁標準設計登入頁面時,這些限制會導致版面配置破裂、品牌資產遺失以及登入按鈕失效,直接影響客戶滿意度和數位互動。本指南提供了這些挑戰的解決方案,介紹了防禦性編碼實踐 — 例如內聯 CSS、Base64 資產編碼、系統字型堆疊以及明確的導覽驅動驗證交握 — 以確保無縫的跨平台渲染。此外,我們還探討了利用像 Purple 的 portal 產生器這樣的託管解決方案,如何讓開發人員在保持完整的 HTML/CSS 創意控制的同時,卸載 RADIUS 驗證、資料庫擴充、GDPR/PCI 合規性以及多廠商 AP 整合 [3]。

技術深挖

要建置具有彈性的自訂 Captive Portal,開發人員必須了解當訪客與開放式服務設定識別碼 (SSID) 建立關聯時發生的網路層級攔截和瀏覽器虛擬化。

Captive Portal 生命週期

當用戶端裝置與 captive SSID 建立關聯時,會觸發以下順序:

  1. IP 關聯:裝置完成 3 向交握並透過 DHCP 請求 IP 位址。
  2. 主動連線能力探測:作業系統的背景網路管理員立即向專用的廠商中立 canary URL(例如 Apple 的 http://captive.apple.com/hotspot-detect.html 或 Google 的 http://connectivitycheck.gstatic.com/generate_204)傳送 HTTP GET 請求 [1]。
  3. DNS/HTTP 攔截:本地無線區域網路控制器 (WLC) 或存取點 (AP) 攔截此 port 80 HTTP 請求。閘道器不會回傳預期的 HTTP 200 或 204 狀態,而是透過 HTTP 302 重新導向將用戶端的流量重新導向到 Captive Portal 的登入頁面 URL [2]。
  4. Webview 產生:偵測到重新導向後,作業系統會產生其原生的 Captive Network Assistant (CNA) 微型瀏覽器以顯示重新導向的登入頁面,從而無需使用者手動開啟完整瀏覽器。
  5. 驗證與狀態轉換:使用者完成登入表單,將憑證提交回 portal 伺服器,該伺服器指示閘道器(通常透過 RADIUS Access-Accept 或外部 API 呼叫)授權 MAC 位址。
  6. CNA 退出交握:CNA 微型瀏覽器向其 canary URL 執行另一個 HTTP GET。如果收到預期的 200/204 回應,它會將右上角的按鈕從「取消」變更為「完成」,並將 WiFi 連線確立為主要網路介面。

平台專屬的微型瀏覽器限制

每個作業系統在不同的 webview 環境中處理此生命週期,導致高度碎片化的行為。下表詳細說明了這些關鍵限制:

平台 / Webview 顯示方式 持久性 Cookie 外部網路字型 JavaScript 執行 視窗尺寸 退出交握觸發器
Apple iOS CNA (Websheet) 微型瀏覽器彈出視窗 已封鎖(關閉時銷毀) 已封鎖(離線) 受限(無 localStorage/sessionStorage) 響應式(裝置寬度) 僅限全頁 HTTP 重新導向 [1]
Apple macOS CNA (Captive Network Assistant) 微型瀏覽器彈出視窗 已封鎖 已封鎖 受限(無警告/確認對話方塊) 固定 (900px x 572px) 僅限全頁 HTTP 重新導向
Android (Google) (CaptivePortalLogin) 推播通知 -> Chrome Custom Tab 允許(與 Chrome 共用) 允許(若列入 walled garden 白名單) 完整 響應式 自動(Captive Portal API / 204 檢查) [2]
Android (Samsung) (Samsung Internet) 推播通知 -> 微型瀏覽器 允許 允許 完整 響應式 自動
Windows 10/11 (預設瀏覽器) 自動啟動預設瀏覽器 允許(完整瀏覽器環境) 允許 完整 響應式 手動 / 自動

cna_constraints_comparison.png

避開 Apple CNA「完成」按鈕陷阱的編碼方法

自訂 portal 開發中最常見的失敗模式之一是 iOS 裝置上的 「完成」按鈕陷阱。當使用者進行驗證時,iOS Websheet webview 必須偵測到網路不再處於 captive 狀態。它透過監控其背景 canary 請求的成功與否來做到這一點。

至關重要的是,iOS CNA 僅在全頁 HTTP 導覽(位置重新導向)時才會觸發此檢查。如果開發人員建置了一個現代單頁應用程式 (SPA),該程式透過非同步 AJAX 呼叫(例如 fetch()Axios)提交表單資料並動態更新 DOM 而不變更 URL,則 CNA 將 永遠不會 重新執行其連線能力檢查。使用者將在閘道器層級完成驗證,但右上角的 CNA 按鈕仍將保持為「取消」。如果感到沮喪的使用者按一下「取消」,iOS 裝置將立即中斷連線與 SSID 中斷連線,並終止 WiFi 工作階段 [1]。

為了防止這種情況,驗證成功處理常式 必須 執行整頁重新導向至實際的到達網頁(例如 window.location.href = '/success'),或透過標準 HTTP POST 動作原生提交登入表單。

實作指南

為了確保在所有平台上呈現一致,開發人員必須從現代、高度依賴外部資源的網頁設計,轉變為高度獨立、防禦性的編碼風格。

黃金法則:針對零網路連線進行設計

在 captive 狀態下,用戶端裝置無法存取外部網際網路。它只能解析並存取無線控制器 Walled Garden(圍牆花園)中明確列入白名單的 IP 位址和網域(例如 Captive Portal 伺服器本身的 IP)。因此,HTML 中參照的任何外部資源都將無法載入,從而導致版面配置損壞。

為了進行防禦性設計,請實作以下行動優先 Captive Portal 設計檢查清單

mobile_first_checklist.png

1. 檢視區(Viewport)設定

為了防止行動裝置將檢視區縮小到桌上型電腦的寬度(通常為 980px),HTML `` 必須包含回應式檢視區 meta 標記。如果沒有此標記,文字和輸入欄位在行動裝置上會顯得極其微小:


2. 內聯 CSS 並移除外部依賴項

切勿連結到外部 CSS 檔案或 CDN(例如 Bootstrap、Tailwind 或 Google Fonts)。所有 CSS 必須內嵌在 HTML `` 的 `

<div class="portal-card">
    <div class="logo-container">
        
        
            
            您的品牌
        
    </div>
    
    <h1>歡迎使用訪客 WiFi</h1>
    <p>請在下方輸入您的資訊,以取得安全、高速的網路連線。</p>
    
    
    
        <div class="form-group">
            姓名
            
        </div>
        
        <div class="form-group">
            電子郵件地址
            
        </div>
        
        <div class="consent-group">
            
            
                我同意 <a href="#">服務條款</a> ,並同意依據 GDPR 規範進行資料處理。
            
        </div>
        
        <div id="terms_box" class="terms-scrollbox">
            <strong>WiFi 服務條款:</strong><br />
            1. 本服務依現狀提供,不提供任何明示或默示之保證。<br />
            2. 使用者不得從事非法或佔用大量頻寬的活動。<br />
            3. 個人資料之收集僅用於身分驗證與行銷訂閱,並符合我們的隱私權政策。
        </div>
        
        連線至 WiFi
    
    
    <div class="footer">
        由 Purple 提供技術支援 | 安全訪客 WiFi
    </div>
</div>

## 疑難排解與風險緩釋

部署自訂編碼的 HTML/CSS Captive Portal 時,IT 營運團隊經常會遇到幾項嚴重的營運風險:

### 1. SSL/TLS 憑證警告迴圈

由於 Captive Portal 的運作原理是攔截流量,因此它們與現代 HTTPS 網路安全存在根本性的衝突。當使用者嘗試造訪 HTTPS 網站(例如 `https://www.google.com`),而閘道器嘗試將該流量重新導向至 HTTP Captive Portal 時,瀏覽器會偵測到 SSL 憑證不符,並顯示嚴重的「您的連線不是安全連線」安全警告。

* **緩釋措施**:切勿嘗試直接攔截 HTTPS 流量。完全依賴作業系統原生的 CNA 輔助程式(它會發送未加密的 HTTP 請求以觸發重新導向)。確保您的 Captive Portal 網域擁有有效且受公開信任的 SSL 憑證(例如 Let's Encrypt 或 DigiCert),並且*僅在*初始 HTTP 重新導向成功將使用者引導至您的 Portal 網域後,才透過 HTTPS 提供服務 [2]。

### 2. DNS 解析失敗(圍牆花園陷阱)

如果您的自訂 HTML 頁面引用了外部資源(例如 Facebook、Google 等社群登入 OAuth 端點或付款閘道),除非已在無線控制器的 Walled Garden 中明確將這些網域列入白名單,否則這些網域的 DNS 請求將會失敗。如果白名單中遺漏了某個網域,登入流程將會停滯,並顯示空白畫面。

* **緩釋措施**:維持嚴格且最小化的 Walled Garden 清單。如果使用社群登入,請將身分驗證提供商建議的特定萬用字元網域(例如 `*.google.com`、`*.gstatic.com`)列入白名單。

### 3. 工作階段逾時與 MAC 詐騙漏洞

標準的 Captive Portal 是根據裝置的 MAC 位址進行驗證。然而,現代行動作業系統(iOS 14+ 和 Android 10+)預設使用隨機 MAC 位址(專用 WiFi 位址),並定期輪替。這可能會導致訪客被反覆要求重新驗證,從而破壞使用者體驗 [1]。

* **緩釋措施**:在 RADIUS 伺服器上設定合理的工作階段逾時(例如 24 小時)以防止過期工作階段,並利用 **Passpoint (Hotspot 2.0)** 或 **WPA3-Enterprise** 等現代驗證標準,實現無縫、安全的上網體驗,完全繞過基於 MAC 的 Captive Portal。

## Purple 產品關聯性:自建還是購買

雖然編寫單個 HTML 頁面非常簡單,但託管、保護和擴充自訂 Captive Portal 基礎架構卻面臨著巨大的技術和合規障礙。下表比較了自行託管自訂 Portal 與使用 Purple 的託管企業平台在工程和營運方面的實際情況:

| 功能 / 營運需求 | 自行託管的自訂 Portal | Purple 企業級 WiFi 平台 |
| :--- | :--- | :--- |
| **HTML/CSS 自訂** | 完全手動編碼,將檔案上傳到個別 AP 或本機網頁伺服器。 | **像素級精準的開發人員編輯器**,支援自訂 HTML/CSS 嵌入,並結合拖放式視覺化建構工具。
| **RADIUS 基礎架構** | 必須部署、設定和維護高可用性的 FreeRADIUS 或 Cloud RADIUS 伺服器 [4]。 | **內建、全球分佈的雲端原生 RADIUS**,具備雙活(Active-Active)備援和 99.99% 的可用性 SLA。
| **多廠商 AP 支援** | 每個硬體廠商(Cisco、Aruba、Meraki、Ruckus)都需要自訂整合指令碼 [5]。 | **原生、開箱即用的整合**,支援超過 200 種硬體型號;在混合硬體資產中實現統一的 Portal 部署。
| **資料隱私與合規性** | 場所需承擔 GDPR、CCPA 和 PCI DSS 合規性的 100% 法律責任,包括安全的資料庫加密和資料刪除工作流程。 | **設計上完全合規**。內建同意管理、自動化資料主體刪除請求,以及安全的 ISO 27001 認證託管。
| **分析與行銷** | 需要建構自訂資料擷取管道並整合第三方行銷工具。 | **企業級分析儀表板**,具備即時人流量追蹤、回訪率指標和自動化行銷活動觸發器 [6]。
| **身分驗證提供商整合** | 與 Google、Facebook、Apple 和本機 SMS 閘道進行手動 OAuth2 整合。 | 與主要社群平台、SMS 閘道以及適用於企業訪客的 Azure AD / Okta 進行**一鍵整合**。

Purple 的平台解決了「自建還是購買」的兩難困境。它為開發人員提供了自訂 HTML/CSS 工作區的完整創作自由,同時消除了大規模支援安全 RADIUS 驗證所需之複雜、高風險的後端基礎架構工程。

## 投資報酬率與商業影響

投資於專業設計、響應式的自訂 Captive Portal,可在 IT 營運、行銷和法律合規性方面帶來可量化的回報。

### 1. 降低營運成本(IT 服務台工單)

在大規模部署中(例如體育場或多站點零售連鎖店),故障的 Captive Portal 是導致 IT 服務台呈報案件增加的主要原因。當訪客遇到「白畫面」或無回應的登入按鈕時,他們會讓現場工作人員應接不暇,或提交支援工單。

$$\text{年度支援節省費用} = (\text{年度訪客總造訪次數} \times \text{Portal 故障率} \times \text{服務台聯絡率}) \times \text{每張支援工單的成本}$$

* **S**情境**:一家每年有 1,000,000 名訪客的會議中心。編寫不良的 portal 在較舊的 iOS 裝置上有 5% 的失敗率,導致 10% 的客服中心聯絡率。以業界標準每張支援工單 15 美元計算,營運成本為:
  $$(1,000,000 \times 0.05 \times 0.10) \times \$15 = \$75,000 \text{ 每年可避免的支援開銷}$$
* **結果**:轉換為經過 CNA 優化、行動優先的範本可將 portal 失敗率降低至 &lt;0.1%,幾乎消除了這項營運消耗。

### 2. 行銷數據獲取與訂閱優化

對於零售和餐旅場所而言,顧客 WiFi portal 是獲取乾淨、第一方客戶數據的主要機制。設計不良的使用者介面(帶有微小的文字或笨重的表單版面配置)會導致高**跳出率**——使用者完全放棄登入流程,從而失去行銷機會。

* **案例研究(零售)**:一家全國零售連鎖店採用了利用 Purple 平台且經過行動優先優化的 captive portal。透過將多步驟登入表單替換為單一欄位的電子郵件輸入(字型大小:16px)和優化的 48px 點擊目標按鈕,他們在第一季內實現了**完成註冊量增加 42%** 以及**行銷電子報訂閱量增加 28%** [6]。

### 3. 法律與合規風險緩解

在 GDPR 和 CCPA 的規範下,不合規的數據收集會帶來嚴厲的財務處罰(在 GDPR 下最高可達全球年營業額的 4%)。依賴預先勾選的核取方塊,或未能於 splash 頁面上提供清晰且易於存取的隱私權政策,會使企業面臨巨大的法律責任。

* **緩解投資報酬率 (ROI)**:實施明確、未預先勾選的同意核取方塊,並將條款託管在優化的滾動框中,可確保 100% 的法規合規性,從而降低數百萬美元監管罰款的風險並保護品牌聲譽。

## 重點摘要

* **CNA 沙箱具有限制性**:Apple 的 iOS Websheet 和 macOS CNA 是高度沙箱化的環境,會封鎖外部資產、Cookie 和網頁字型。所有樣式和資產必須是自包含的(行內 CSS、Base64 圖片、系統字型)[1]。
* **AJAX 會破壞 iOS 結束握手**:若要成功將 iOS 裝置從「captive」狀態轉換為「已連線」狀態(將右上角的按鈕從「取消」變更為「完成」),您必須觸發全頁面 HTTP 重新導向。非同步 DOM 更新會使裝置陷入 captive 迴圈。
* **行動優先是強制性的**:超過 90% 的登入發生在行動裝置上。設計單欄版面配置(最大寬度:480px)、利用適合觸控的點擊目標(最小 44px x 44px),並在所有文字輸入框上強制執行至少 16px 的字型大小,以防止 iOS 瀏覽器自動縮放。
* **圍牆花園(Walled Gardens)控制 DNS**:登入期間引用的任何外部網域(例如社群登入 API)都必須明確列入無線控制器的圍牆花園白名單中,否則頁面將無法載入。
* **Purple 消除後端複雜性**:利用 Purple 的 portal 產生器,開發人員可以透過自訂編輯器獲得完整的 HTML/CSS 控制權,同時減輕 RADIUS、多廠商 AP 整合以及符合 GDPR 規範的資料庫管理所帶來的巨大安全性、擴充性和合規性負擔 [3]。

## 參考資料

* [1] [無線寬頻聯盟:Captive Network Portal 行為](https://captivebehavior.wballiance.com/)
* [2] [Android 開源專案:Captive Portal 登入 Webview 整合](https://source.android.com/docs/core/connect/android-custom-tabs-captive-portal)
* [3] [歐洲資料保護委員會:關於第 2016/679 號條例下同意的指南](https://edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-052020-consent-under-regulation-2016679_en)
* [4] [如何使用 Cloud RADIUS 實施 802.1X 驗證](/guides/implementing-8021x-with-cloud-radius)
* [5] [Cisco 無線 AP:2026 年產品與部署指南](/blog/cisco-wireless-ap)
* [6] [Purple WiFi 行銷與分析平台](/guest-wifi-marketing-analytics-platform)

---

## 收聽技術簡報

收聽資深解決方案架構師討論自訂 captive portal 的技術限制和實施策略:

關鍵定義

Captive Portal

在向新連接 Wi-Fi 網路的使用者授予更廣泛的網路資源存取權限之前,向其顯示的網頁,通常用於驗證、付款或顯示服務條款。

IT 團隊在閘道器層級部署 Captive Portal,以控制訪客存取、收集使用者資料並執行法律合規性。

Captive Network Assistant (CNA)

作業系統(例如 Apple iOS 和 macOS)在偵測到 captive 網路重新導向時自動產生的、受到高度限制且處於沙箱環境中的微型瀏覽器,其設計目的僅在於協助進行 portal 驗證。

CNA webviews 執行嚴格的限制,包括封鎖外部 CDN、持久性 Cookie 和本機儲存,這經常會破壞標準的網頁設計。

Walled Garden

在完成 Captive Portal 登入流程之前,允許未經驗證的訪客使用者透過閘道器存取的 IP 位址、子網路或網域名稱的受限清單。

開發人員必須確保任何外部資源(例如社群登入 API 或付款閘道器)都已列入 walled garden(圍牆花園)白名單,以防止登入流程停滯。

Base64 Encoding

一種二進位轉文字的編碼配置,將二進位資料(例如圖片)表示為 ASCII 字串,允許將資產直接嵌入到 HTML 或 CSS 文件中。

對標誌和圖示使用 Base64 編碼可消除外部 HTTP 請求,確保資產在離線 CNA 環境中完美渲染。

RADIUS (Remote Authentication Dial-In User Service)

一種網路協定,為連接和使用網路服務的使用者提供集中式的驗證、授權和計費(AAA)管理。

一旦滿足驗證條件,Captive Portal 伺服器就會與 RADIUS 伺服器進行通訊,以在網路閘道器端授權訪客的 MAC 位址。

System Font Stack

一種 CSS font-family 宣告,其優先使用預先安裝的作業系統字型(例如 iOS 上的 San Francisco、Windows 上的 Segoe UI 和 Android 上的 Roboto),而非外部網路字型。

實作系統字型堆疊可確保立即進行排版渲染,而不會觸發對 Google Fonts 等服務的被封鎖外部 HTTP 請求。

Canary URL

由作業系統廠商維護的專用、未加密的 HTTP URL(例如 captive.apple.com),用於測試裝置是否具有不受限制的網際網路連線能力。

作業系統背景網路管理員會檢查此 URL,以偵測是否存在 Captive Portal 並觸發 CNA webview 彈出視窗。

Passpoint (Hotspot 2.0)

由 Wi-Fi Alliance 開發的產業標準,使行動裝置能夠自動偵測 Wi-Fi 熱點並與其進行安全驗證,從而繞過手動的 Captive Portal 登入。

企業將 Passpoint 與 Purple 等平台結合使用,使訪客從繁瑣的登入頁面過渡到無縫、類似行動網路的安全漫遊體驗。

範例

一家擁有 250 間客房的奢華連鎖酒店 [Hospitality](/industries/hospitality) 希望實作一個完全符合其高端品牌指南的自訂訪客 WiFi 登入頁面。他們的創意代理商設計了一個登入頁面(splash page),其中使用了自訂品牌字型(託管於 Adobe Fonts)、多張高解析度背景圖片(託管於公開的 AWS S3 儲存桶)以及多步驟動畫 JavaScript 精靈。部署後,iOS 訪客連接到 SSID,但 portal 彈出時顯示為空白畫面,且使用者無法進行驗證。

為了解決空白畫面和品牌呈現破裂的問題,我們必須重構 portal 的前端架構,以符合 Apple CNA 沙箱限制:

  1. 字型修復:由於 Adobe Fonts 需要外部 HTTP 請求,而該請求會被 CNA 封鎖,因此我們將自訂字型呼叫替換為原生的高端系統字型堆疊(font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;)。這可確保在沒有外部網路呼叫的情況下立即進行渲染。
  2. 資產最佳化:AWS S3 上的背景圖片被封鎖,因為 S3 不在閘道器的 walled garden(圍牆花園)中。我們壓縮主要品牌標誌,將其轉換為輕量級的 SVG,並將其作為 Base64 Data URI 直接編碼在 HTML 中。對於背景,我們使用酒店的品牌色彩,以乾淨、響應式的 CSS 漸層取代沉重的圖片,從而大幅減輕頁面重量。
  3. JavaScript 簡化:多步驟動畫精靈依賴外部 jQuery 和 GSAP 程式庫。我們移除這些外部依賴項,並將表單重構為單頁、單欄的 HTML 結構。表單驗證使用輕量級的原生 JavaScript 重寫。
  4. 驗證交握:表單提交方式從基於 AJAX 的提交修改為原生 HTML <form action="/submit" method="POST">,以觸發全頁重新導向,從而允許 iOS Websheet 執行其 canary 檢查並顯示「完成」按鈕。
考官評語: 此情境代表了高端創意設計與 captive webview 嚴格安全限制之間的經典衝突。創意代理商通常會將 Captive Portal 視為標準的桌上型電腦網站。然而,由於裝置處於未驗證狀態,網路會封鎖所有外部流量。透過將 CSS 內聯、使用系統字型堆疊、對資產進行 Base64 編碼以及使用原生表單提交,我們在保留高端品牌美學的同時,在 iOS 和 Android 裝置上實現了 100% 的運作可靠性。

一家擁有 450 家門市的連鎖零售商 [Retail](/industries/retail) 希望透過 WiFi 登入頁面收集訪客電子郵件,以充實其 CRM。他們要求訪客選擇訂閱行銷電子報。最初的設計包含一個預先勾選的「我同意接收行銷電子郵件」核取方塊。此外,該 portal 託管於其總部的單一本地伺服器上。在尖峰時段(週六下午),全國各地的訪客都遇到了嚴重的延遲,許多人無法載入登入頁面,導致資料收集率大幅下降。

我們必須同時解決合規性違規和基礎設施瓶頸問題:

  1. 合規性修復:在 GDPR 和 CCPA 規範下,預先勾選的同意方塊是非法的。我們修改 HTML,使行銷同意核取方塊預設為未勾選(<input type="checkbox" id="marketing_consent">)。我們還為服務條款添加了一個獨立的強制性核取方塊,以將法律協議與行銷訂閱解耦。
  2. 基礎設施擴充:將全國性的 Captive Portal 託管在單一集中式伺服器上會造成單一故障點和巨大的延遲瓶頸。我們將 portal 前端遷移到具有邊緣快取、高可用性且全球分佈的內容傳遞網路(CDN)。
  3. RADIUS 整合:我們設定本地門市的存取點,使其指向具有主動-主動(active-active)備援的雲端原生 RADIUS 叢集,確保即使在週六尖峰流量期間,驗證請求也能在邊緣本地進行處理,且延遲低於 50 毫秒。
  4. Purple 遷移:為了消除這整個工程開銷,該零售商遷移到了 Purple。Purple 內建的 GDPR 同意工具會自動管理合規的訂閱,其全球分佈的雲端基礎設施每天處理數百萬次驗證,可用性達 99.99%,徹底解決了擴充瓶頸。
考官評語: 預先勾選的同意核取方塊代表嚴重的合規風險,可能導致鉅額監管罰款。將行銷同意與服務條款解耦是技術和法律上的最佳實踐。在基礎設施方面,集中託管 Captive Portal 是一種反模式(anti-pattern)。全國性的零售版圖需要去中心化、邊緣快取的前端,並結合雲端原生的 RADIUS 後端。遷移到像 Purple 這樣的託管平台可以消除這種架構複雜性,使零售商能夠專注於行銷活動,而不是資料庫擴充。

練習題

Q1. 一家大型國際機場 [Transport](/industries/transport) 的 IT 團隊部署了一個自訂編碼的 Captive Portal。他們注意到,雖然 Android 使用者可以無縫連接,但很大一部分 iOS 使用者遇到了成功驗證但無法瀏覽網頁的問題。仔細檢查後,iOS 裝置顯示已連接到 SSID,但 captive 彈出視窗右上角的按鈕仍然顯示「取消」而不是「完成」。此問題的根本原因是什麼?開發人員應該如何修復它?

提示:分析 Apple CNA 協助程式如何偵測網路已從 captive 狀態轉換為已驗證狀態,以及需要什麼瀏覽器動作來觸發此檢查。

查看標準答案

根本原因在於 portal 的成功頁面是透過 JavaScript(AJAX/SPA 路由)動態更新 UI,而不是執行全頁 HTTP 導覽。Apple iOS Captive Network Assistant (CNA) 微型瀏覽器僅在發生全頁 URL 重新導向或導覽時,才會重新執行其背景連線能力檢查(對 captive.apple.com 的 canary 請求)。如果開發人員透過 AJAX 提交登入表單,並僅在 DOM 中顯示「成功」訊息,則 CNA 將無法得知網路已解鎖。因此,右上角的按鈕仍保持為「取消」。如果使用者按一下「取消」退出,作業系統會判定登入失敗並中斷與 WiFi 網路的連線。

解決方案:開發人員必須修改驗證成功處理常式以強制進行全頁重新導向。這可以透過標準 HTML <form action="/submit" method="POST"> 原生提交登入表單,或在 API 回傳成功驗證回應後在 JavaScript 中執行 window.location.href = '/success_landing_page' 來實現。這會觸發所需的全頁載入,強制 CNA 協助程式重新評估網路狀態,驗證現在是否可以存取 canary URL,並將右上角的按鈕變更為「完成」。

Q2. 一個體育場營運團隊 [Events] 希望推出一個可收集行銷訂閱的訪客 WiFi 網路。合規官堅持 portal 必須 100% 符合 GDPR 規範。開發團隊展示了一個模型,其中登入表單包含一個預先勾選的方塊,內容為「我同意服務條款並同意接收行銷電子報」。為什麼這種設計不合規?應該如何重構 HTML/CSS 和表單結構以滿足 GDPR,同時保持高轉換率?

提示:考量 GDPR 對於明確同意、將行銷訂閱與服務條款解耦,以及法律條文在行動裝置螢幕上的實際可見性的嚴格要求。

查看標準答案

所提出的設計在兩個主要方面違反了 GDPR:首先,預先勾選的核取方塊不構成有效的同意,同意必須是自由給予、具體、知情且明確的。其次,將行銷同意與同意服務條款捆綁在一起是不合規的;不能強制使用者接受行銷電子郵件作為使用 WiFi 服務的條件。

重構策略

  1. 解耦同意:將核取方塊拆分為兩個獨立的核取方塊。核取方塊 A 是強制性的,涵蓋服務條款和隱私權政策。核取方塊 B 是選填的,涵蓋行銷電子報訂閱。
  2. 設定為未勾選:確保 HTML 中預設未勾選這兩個核取方塊(省略 checked 屬性)。
  3. CSS 可見性:由於超過 90% 的使用者使用行動裝置,請將核取方塊直接放置在「連接」按鈕上方,以便在不捲動的情況下在「首屏」(above the fold)可見。使用系統字型堆疊,並將標籤字型大小設定為 14px,行高(line-height)設定為 1.4,以提高可讀性。
  4. 條款捲動方塊:為了防止法律條文將表單元素擠出螢幕,請將詳細的服務條款放在具有固定高度的捲動容器中(max-height: 100px; overflow-y: auto; background-color: #F5F1ED; border: 1px solid #D1D5DB; border-radius: 6px;),該容器可以透過文字連結切換開啟或關閉。這在確保絕對法律合規的同時,保持了乾淨且高轉換率的版面配置。

Q3. 一家連鎖零售商 [Retail](/industries/retail) 正在 100 家門市部署自訂編碼的登入頁面。設計師使用了 Google Fonts (Montserrat),並在 HTML head 中連結到 CDN 託管的 Bootstrap 樣式表。在公司網路進行測試期間,頁面渲染非常美觀。然而,當部署到具有 captive 網路設定的測試門市 AP 時,頁面渲染卻顯示為未套用樣式的 Times New Roman 文字、對齊破裂且缺少圖示。為什麼會發生這種情況?資產必須如何重構?

提示:分析使用者驗證前網路連線的狀態,並確定瀏覽器如何處理對 walled garden(圍牆花園)以外網域的外部 HTTP 請求。

查看標準答案

此失敗是由於在載入登入頁面時,裝置處於未驗證的 captive 狀態。在此狀態下,無線閘道器會封鎖所有連外網際網路流量,僅允許對閘道器 Walled Garden(圍牆花園)中明確列入白名單的網域進行請求。由於 Bootstrap (cdn.jsdelivr.net) 和 Google Fonts (fonts.googleapis.com) 的 CDN 網域未列入白名單,瀏覽器獲取樣式表和字型檔案的請求會靜默失敗。因此,瀏覽器會退回到其預設的渲染引擎,導致未套用樣式的 HTML(Times New Roman 文字)和破裂的版面配置。

重構策略

  1. 內聯 CSS:移除外部 Bootstrap 樣式表連結。將必要的 CSS grid/flexbox 規則直接複製到 HTML <head> 中的 <style> 區塊中。這可確保所有版面配置指令都在初始的單頁負載中傳遞。
  2. 實作系統字型堆疊:移除 Google Fonts @import<link> 呼叫。在 CSS 中將其替換為原生系統字型堆疊(font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;)。這會強制裝置使用作業系統中已預先安裝的高品質字型,從而完全消除外部網路依賴性。
  3. 對圖示/標誌進行 Base64 編碼:如果版面配置依賴外部圖片或圖示庫(如 FontAwesome),請將這些圖示轉換為 SVG 格式,並直接嵌入到 HTML 中,或在 CSS 中作為 Base64 Data URI 嵌入。這保證了頁面是 100% 自包含的,即使在完全沒有網際網路連線的情況下也能完美渲染。