我要把網站的中文字型從線上載入改成自己放,理由是隱私:不想每個訪客都連一次別人的伺服器。第一步很自然,把那行樣式表網址用程式抓下來看看裡面指到哪些檔。
它回 200。內容是乾淨的 CSS,兩個 @font-face,一個常規、一個粗體,指向兩個 .ttf 檔。
我把兩個檔下載下來,才發現每一個都 7 MB。
同一個網址,三種身分,三種答案
────────────────────────────────────────────
誰在問 回什麼 大小
────────────────────────────────────────────
curl 2 個 @font-face 466 B
truetype 單檔 7,090,820 B
Firefox 38 2 個 @font-face 460 B
woff 單檔 4,161,364 B
Chrome 131 210 個 @font-face 240,368 B
woff2 切片 每片約 9 KB 起
────────────────────────────────────────────
三次都是 HTTP 200
我以為發生了什麼
我以為樣式表就是一個檔案:網址固定,內容固定,誰來抓都一樣。所以我把程式抓到的那份當成瀏覽器平常用的那份,開始盤算「兩個 7 MB 的字型檔要怎麼快取」。
我甚至覺得中文字型本來就這麼大,這是自架的代價。
實際發生了什麼
2026-09-19 實測,同一個 css2 網址,只換 User-Agent。
用 curl 的預設身分抓:466 位元組,2 個 @font-face,格式 truetype,字型檔 HEAD 回 7,090,820 位元組。換成 2015 年的 Firefox 38:460 位元組,2 個 @font-face,格式 woff,單檔 4,161,364 位元組。換成 Chrome 131:240,368 位元組,210 個 @font-face,格式 woff2,而且每一個都帶 unicode-range,把中文字集切成 105 片一組、兩個字重共 210 片,瀏覽器只下載頁面上真的用到的那幾片。
同一個網址,回應的樣式表差了五百倍,字型檔的切法完全不同。 三次都是 200,三次都是合法 CSS,沒有任何一次提示「你拿到的是降級版」。
回應標頭裡其實有線索:Cache-Control: private,還有一個 Vary 標頭。private 的意思就是這份內容是針對你這個請求端產的,不能拿給別人用。我第一次抓的時候沒看它。
官方文件寫了嗎
有寫,但寫在「為什麼要用我們的線上服務」那一段,不是寫在「自架時要注意」那一段。官方說明服務會依瀏覽器送出最適合的格式,這句話本身就是答案:它依瀏覽器決定內容,而 curl 不是瀏覽器。
工具沒做錯。給一個不認得的客戶端最保守的格式,是合理的設計。錯的是我把「依瀏覽器產生的樣式表」當成靜態檔在抓。 它沒有騙我,它只是照我的身分回答。
你一定會踩的那個細節
真正會踩到的不是字型變大,是你拿程式抓下來的那份去自架,然後在正式環境量到「每個訪客第一次載頁要多下載 7 MB」,卻以為那是中文字型的天性。
抓樣式表的時候,把 User-Agent 換成你的使用者真的在用的瀏覽器,並且抓完先數 @font-face 有幾個。 今天就能自己跑一次:
同一個網址抓三次,只換身分: U="https://fonts.googleapis.com/css2" U="$U?family=Noto+Sans+TC:wght@400;700&display=swap" 1. 程式預設身分 curl -s "$U" | grep -c "@font-face" → 看到 2,就是保守版 2. 換成現代瀏覽器 UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64)" UA="$UA AppleWebKit/537.36 (KHTML, like Gecko)" UA="$UA Chrome/131.0.0.0 Safari/537.36" curl -s -A "$UA" "$U" | grep -c "@font-face" → 看到 210,這才是瀏覽器拿到的那份 3. 看它是不是「看人給」 curl -sI "$U" | grep -i "cache-control\|vary" → private 加 Vary,就代表內容隨請求端變 數字差一百倍,就不要把第 1 步那份拿去自架。
第 3 步平常就該養成習慣:任何回 Cache-Control: private 的東西,都不要當成「抓一次、大家共用」的靜態檔。
站內延伸
來源: fonts.googleapis.com/css2 端點(Noto Sans TC 400/700)與 fonts.gstatic.com 字型檔的 HEAD 回應,三種 User-Agent 各一次,皆為 2026-09-19 當日實測。
一個網址不一定對應一份內容。回 200 只證明它願意回答你,不證明它回答的是你要問的那一版;當回應標頭寫著 private,它其實已經告訴你了。