Astro CSP 設定 inline script 與 style 前,先用 Report-Only 找出阻擋
替靜態網站加 Content Security Policy(CSP)時,最常見的失敗不是 header 少寫一個,而是直接在 production 啟用嚴格 policy,才發現 inline script、style 或第三方 widget 被瀏覽器擋掉。Astro 7.1 在 7 月帶來更細緻的 inline scripts 與 styles CSP directive 控制;它讓設定更精準,但不會自動替你的部署找出所有允許來源。
因此,升級或導入時先把 CSP 視為可觀察的設定變更,而不是一次性的安全勾選。
先列出頁面真正執行與載入的東西
在改 Astro 設定前,先用瀏覽器 DevTools 的 Network 與 Console,挑首頁、文章頁、搜尋頁各跑一次。記錄下列項目:
| 類型 | 要記錄的值 | 常被遺漏的來源 |
|---|---|---|
| Script | script 的來源網域與 inline block | 分析、留言、廣告或搜尋 widget |
| Style | 外部 stylesheet 與 runtime style injection | 字型服務、元件庫、theme 切換 |
| Connect | fetch、analytics beacon、search API | Pagefind 或第三方觀測服務 |
| Image/Font | 實際 asset 網域 | CDN、社群預覽與字型 CDN |
只從程式碼搜尋 script 不夠,因為 integration 或部署平台可能額外插入資源。這個清單會是你審查 CSP directive 的依據。
先以 Report-Only 觀察,再收緊 policy
第一版建議用 Content-Security-Policy-Report-Only 部署,讓瀏覽器回報違規但不阻擋頁面。確認一個完整的發布週期後,再把已驗證的 directive 換成強制 Content-Security-Policy。Report endpoint 的保存方式依 hosting 而異;沒有 endpoint 時,至少在測試環境開 DevTools Console 檢查主要頁面。
第 1 階段:Report-Only,收集實際違規來源第 2 階段:明確加入必要來源,移除不再使用的寬鬆規則第 3 階段:啟用強制 CSP,部署後再巡一次核心頁面不要為了快速消除錯誤直接放入過寬的 unsafe-inline 或萬用網域。若某個 inline 行為是必要的,先確認 Astro 7.1 新增的 directive 選項是否能更精準表達需求,再決定要調整程式碼、nonce/hash 策略或 policy。
Astro 升級和 CSP 修改分兩次驗證
Astro 官方建議以 @astrojs/upgrade 或套件管理器升級。若專案還在較舊 major version,將 major 升級、依賴更新與 CSP 收緊分成可回退的兩個 PR:第一個只確認 build、內容集合與部署正常;第二個才加入 Report-Only 與 directive 變更。這樣在搜尋、樣式或 hydration 出現問題時,才知道是 framework 升級還是 CSP 造成的。
pnpm upgrade astro --latestpnpm checkpnpm build上面指令只適合已決定升級的分支;先看 lockfile、integration 相容性與 CI,再執行相依更新。本站已有 Astro Sitemap 的排除規則 與內容建置設定,升級時也應一起跑 sitemap、搜尋與文章頁驗證。
完成條件
一份可維護的 CSP 設定,至少能回答:每個允許來源對應哪個頁面功能、Report-Only 曾觀察到哪些違規、強制 policy 後核心頁面是否仍正常,以及下一次新增第三方服務時由誰更新清單。把這些放進 deployment checklist,CSP 才不會在下一次改版變成難以追查的白頁來源。
參考資料:
回報錯字、失效連結,或告訴我你想看的延伸主題。