WordPress 快取 Header 排查:用 curl、Network 與回滾紀錄判斷誰在快取頁面

WordPress 前台明明已經更新文章、選單或 CSS,訪客卻還看到舊畫面時,最常見的反應是「清快取」。問題是,清哪一層?外掛快取、主機快取、CDN、瀏覽器、Object Cache,甚至是反向代理,都可能在回應裡留下線索。
如果只靠重新整理頁面,很容易把不同快取層混在一起。比較穩的做法,是先把 HTTP header 與瀏覽器 Network 證據留下來,再決定要 purge 哪一層,最後用同一組檢查確認內容真的刷新。
這篇整理一份 WordPress 快取 Header 排查紀錄,適合用在「後台已發布、前台仍舊版」、「CSS 改了但 production 沒變」、「CDN purge 後仍 HIT」這類維護情境。
先把症狀寫成可重現路徑
不要一開始就清所有快取。先定義一個具體 URL、一個可辨識的內容變更,以及你在哪個環境看到舊畫面。
Observe:
- URL: https://example.com/news/sample-post/
- WordPress 後台文章標題已改成「2026 更新版」。
- 無痕視窗仍看到舊標題。
- 手機 5G 網路看到新標題,辦公室 Wi-Fi 看到舊標題。
- 最近剛啟用 CDN 與 Page Cache 外掛。
這段紀錄能幫你分辨:問題可能是地區節點、登入狀態、瀏覽器快取、CDN cache key,還是 WordPress 本身沒有成功發布。
用 curl 看狀態碼與快取標記
先用 curl -I 看 header,不要只看 body 內容。若站台會壓縮或 redirect,建議加上 -L 跟隨轉址,並記錄最後一跳的資訊。
curl -L -I https://example.com/news/sample-post/
我會優先看這幾種欄位:
HTTP/2 200
cache-control: public, max-age=3600
age: 842
x-cache: HIT
cf-cache-status: HIT
last-modified: Mon, 17 Aug 2026 00:58:00 GMT
etag: "abc123"
這些欄位不一定每個環境都有,但只要出現 HIT、age 或長時間 max-age,就代表某一層可能正在回舊內容。若 age 持續增加,通常表示你打到的是快取副本,而不是 WordPress 即時產生的頁面。
分開檢查 HTML、CSS 與圖片
同一個頁面可能 HTML 已刷新,但 CSS 或圖片還在舊版本。排查時不要只測首頁,要把可疑資源拆開看。
curl -L -I https://example.com/news/sample-post/
curl -L -I https://example.com/wp-content/themes/example/style.css
curl -L -I https://example.com/wp-content/uploads/2026/08/cover.jpg
紀錄時可以用這種表格:
| 資源 | status | content-type | cache 標記 | 判斷 |
|---|---|---|---|---|
| 文章 HTML | 200 | text/html | cf-cache-status: HIT | 可能是 CDN 頁面快取 |
| theme CSS | 200 | text/css | age: 0 | CSS 已刷新 |
| cover image | 200 | image/jpeg | x-cache: HIT | 圖片可接受長快取 |
圖片長快取不一定是錯;HTML 長期 HIT 才需要特別小心,尤其是文章、分類頁、購物車、會員頁或表單頁。
用瀏覽器 Network 驗證真實使用者路徑
curl 很適合做快速證據,但瀏覽器還會帶 cookie、service worker、cache mode 與不同 Accept header。因此排查前台問題時,我會再用 DevTools Network 做一次使用者視角檢查。
建議記錄:
- Request URL 是否是 canonical URL,還是被導到另一個語系、手機版或 AMP。
- Status 是
200、301、304還是from disk cache。 - Response Headers 裡的
cache-control、age、x-cache、cf-cache-status。 - Disable cache 勾選後重新整理,畫面是否改變。
- 登入與未登入狀態是否回同一份 HTML。
如果只有未登入訪客看到舊內容,通常是 Page Cache / CDN;如果登入者也看到舊內容,可能是 WordPress 內容沒有成功更新、Object Cache 回舊查詢,或佈景模板本身沒有讀到新資料。
Purge 前先留下變更與回滾點
快取操作看似安全,但在 production 上仍然要保留最小回滾紀錄。尤其是停用外掛、改 CDN 規則、改 Cache-Control 時,應該留下版本與操作原因。
Change record:
- 09:32 observe: article HTML cf-cache-status=HIT, age=1842。
- 09:36 action: purge CDN single URL /news/sample-post/。
- 09:38 verify: article HTML cf-cache-status=MISS, body contains new title。
- Rollback: 若 purge 規則造成全站 HIT 下降,只恢復 CDN rule,不改文章內容。
這種紀錄能避免下一次出現同類問題時,團隊只記得「上次清快取好了」,卻不知道清的是哪一層。
判斷哪一層負責,不要一次全關
常見判斷方式如下:
| 現象 | 可能層級 | 下一步 |
|---|---|---|
cf-cache-status: HIT 且 age 增加 | CDN | purge 單一 URL 或檢查 Page Rule |
x-cache: HIT 但沒有 CDN header | 主機 / reverse proxy | 查主機快取面板或 Nginx/FastCGI cache |
status 304 且 body 沒下載 | 瀏覽器條件式快取 | hard reload 或檢查 etag / last-modified |
| 登入看新、未登入看舊 | Page Cache 外掛 | 清指定 URL、排除動態頁 |
| 所有人都舊 | WordPress 內容或 Object Cache | 查發布狀態、資料庫、Object Cache |
維護原則是:先 purge 最小範圍,再擴大到分類、首頁、全站。全站 purge 雖然快,但會讓你失去判斷是哪個 cache key 出問題的證據。
驗證要同時看 header 與內容標記
清完快取後,不要只看到 MISS 就收工。也要確認 body 真的包含新內容,並且下一次請求的 cache 行為符合預期。
curl -L -sS https://example.com/news/sample-post/ \
| grep "2026 更新版"
curl -L -I https://example.com/news/sample-post/
理想的驗證紀錄可以這樣寫:
Verify:
- HTML body contains 「2026 更新版」。
- First request: cf-cache-status=MISS。
- Second request: cf-cache-status=HIT, age starts from low value。
- Logged-out browser Network shows status 200, not disk cache。
如果 body 沒變但 header 變了,代表你只是讓快取重新抓了一份舊 HTML;這時就要回到 WordPress 發布狀態、Object Cache 或模板資料來源,而不是繼續 purge CDN。
UCAMC 會把這類檢查留成維護證據
對內容站來說,快取不是只為了速度,也會影響文章發布、SEO 更新與社群預覽。每次遇到快取問題,都應該留下 observe/change/verify/rollback,而不是只留一句「已清快取」。
最小可重用格式如下:
URL:
Expected content:
Observed stale content:
Headers before:
Action taken:
Headers after:
Body verification:
Rollback / note:
這份紀錄未來可以變成站台維護 SOP,也能幫內容、工程與主機供應商快速對齊:現在問題到底在 WordPress、主機、CDN,還是瀏覽器端。