Coolkid mascot CoolkidLab Build in Public. Level up together.

SEO 菜鳥成長史 · #28

閱讀

CSP 擋掉 GA4 / GTM 怎麼辦?3 種被擋情境對照 + 5 分鐘排查 SOP

先講重點

GA4 或 GTM 裝了卻收不到數據,最常見元兇是 CSP(內容安全政策)白名單漏了 Google 的網域。被擋只有 3 種情境:script-src 擋掉載入、connect-src 擋掉上報、GTM 額外需要 frame-src。打開 F12 對照 console 紅字,5 分鐘內能定位是哪一種。

這篇跟之前的連載都不一樣:不是我又踩了新坑,是我第一次照 GSC 的訊號回頭補一篇文。

Lab 的 GSC 查詢裡,csp 相關搜尋從週報 #3 到 #8 連 6 期都有變體命中:csp google analytics、ga4 csp、google analytics csp、csp ga、google tag manager csp,一共 5 個變體。最有感的是 2026-07-15 那期 — 全站點擊崩到只剩 5 個,唯一逆勢進點擊的查詢就是「google tag manager csp」:1 個曝光、1 個點擊,100% 點閱率。

一個主題連 6 週換不同的字來敲門,代表需求真實存在,而我的舊文(#3 的踩坑紀錄)只回答了一半 — 當時我只寫自己撞到的那一種。這篇把 CSP 擋 GA4 / GTM 的 3 種情境一次補齊,附 console 紅字對照跟排查步驟,你不用再自己去翻官方英文文件。

1. 先懂一件事:被 CSP 擋,只有「白名單沒有他」一種原因

CSP(內容安全政策)可以想成網站門口的保全名單:名單上分好幾個欄位 — 誰可以進來執行程式(script-src)、誰可以被連線傳資料(connect-src)、誰可以用內嵌框顯示(frame-src)。每個欄位就是一條 directive(規則)。

所以「GA4 被 CSP 擋掉」不是一種病,是三種:Google 的工具要做三類動作,每一類對應一條規則,漏開哪一條就死在哪一關。好消息是瀏覽器一定會在 console(F12 開發者工具的訊息區)用紅字告訴你是哪一條 — 你要做的只是看懂那行紅字。

2. 情境 1:script-src 擋掉載入 — console 直接紅給你看

症狀:GA4 / GTM 的程式碼根本載不進來,後台永遠是 0。F12 打開 console,會看到這種紅字:

Refused to load the script
'https://www.googletagmanager.com/gtag/js?id=G-XXXX'
because it violates the following Content Security Policy
directive: "script-src 'self' 'unsafe-inline'"

翻成人話:你的 script-src 名單只放了「自家」跟「行內」,googletagmanager.com 不在名單上,瀏覽器直接拒載。解法是在 script-src 補上:

script-src 'self' 'unsafe-inline' https://*.googletagmanager.com;

這就是我 2026-05-11 撞到的那顆鍋 — 自己半個月前鎖的 CSP,把全站 28 頁的 GA 一起悶掉,完整過程在 #3 那篇。當時查半天以為自己貼錯位置,其實 console 第一行就把答案寫在臉上了。

3. 情境 2:connect-src 擋掉上報 — 最陰險,頁面看起來沒事

症狀:程式載進來了、網頁一切正常、你以為裝好了 — 但 GA4 即時報表永遠是 0。因為數據要「傳出去」給 Google 的伺服器,而傳出去走的是 connect-src 這條規則,跟載入是兩關。

Refused to connect to
'https://region1.google-analytics.com/g/collect?...'
because it violates the following Content Security Policy
directive: "connect-src 'self'"

這關陰險在:網頁畫面完全不會壞,不主動開 console 根本不會發現。GA4 上報會打到好幾個端點,官方要求 connect-src 至少放行這三組(萬用字元寫在左側是合法的,能涵蓋 region1 這類地區端點):

connect-src 'self'
  https://*.google-analytics.com
  https://*.analytics.google.com
  https://*.googletagmanager.com;

我自己的站(Vercel 靜態站 + gtag)實測,script-src 一條 + connect-src 這三條就能穩定收數。官方完整清單還包含 doubleclick、google.com 等廣告與 Signals 相關端點 — 有跑 Google Ads 或開 Google Signals 的站才需要,見第 5 節的對照表。

4. 情境 3:用 GTM 的人,還有兩個專屬關卡

先誠實聲明:我自己的站跑的是 gtag(直接埋 GA4),情境 1 跟 2 是親身除錯過的;這一節的 GTM 專屬設定,是我丟給 agent 把 Google Tag Platform 官方 CSP 指南抓回來對照整理的(2026-07-17 查核),不是親身踩坑。

GTM 比 gtag 多兩個關卡。第一,GTM 的預覽 / 除錯模式跟部分容器功能會用到內嵌框,要多開 frame-src:

frame-src https://www.googletagmanager.com;

第二,如果你在 GTM 容器裡用了「自訂 JavaScript 變數」,CSP 還得開 unsafe-eval — 官方文件明講這個權限「只在絕對必要時才用」,並建議改用 Custom Templates 取代。unsafe-eval 等於把門開一個大縫,能不開就不開。

官方推薦的正規做法其實是 nonce(一次性通行碼):伺服器每次出頁面時生一個隨機值放進 script-src,GTM 會自動把這個通行碼傳遞給它注入的所有 script。靜態站做不到「每次請求生隨機值」,所以像我這種 Vercel 靜態站走的是白名單網域法 — 兩條路都合法,看你的架構選。

5. 對照表:哪條規則該放哪些網域(Google 官方清單)

下表整理自 Google Tag Platform 官方 CSP 指南。官方還特別白紙黑字提醒:「每個 Google 頂級網域(TLD)都必須逐一列出,因為 CSP 語法不允許在主機名右側使用萬用字元」— 想偷懶寫 google.* 是不合法的。

directiveGA4(gtag)最小集官方完整清單另含(廣告 / Signals 用)
script-src*.googletagmanager.com
connect-src*.google-analytics.com
*.analytics.google.com
*.googletagmanager.com
*.g.doubleclick.net
*.google.com 與各地區 TLD
pagead2.googlesyndication.com
img-src*.google-analytics.com
*.googletagmanager.com
*.g.doubleclick.net
*.google.com 與各地區 TLD
frame-src(GTM)www.googletagmanager.com

「最小集」欄是我自己站上實測能穩定收數的組合(沒跑廣告、沒開 Signals);右欄是官方完整要求 — 之後要上 Google Ads 再照補,不用一開始全開。來源:Google Tag Platform 官方 CSP 指南(2026-07-17 查核)。

6. 5 分鐘排查 SOP

  1. Step 1 — 開網站按 F12,切到 Console 分頁,重新整理頁面。
  2. Step 2 — 在 console 搜「Refused」。沒有任何紅字?那你的問題不是 CSP,去查 ID 有沒有貼錯或擋廣告外掛。
  3. Step 3 — 讀紅字最後的引號:violates the following … directive 後面寫哪條(script-src / connect-src / frame-src),就是漏開哪關。
  4. Step 4 — 對照第 5 節的表,把該 directive 補上對應網域;改的是出 CSP header 的地方(我是 vercel.json,你的可能在 nginx / meta tag / 主機設定)。改完一定要重新部署。
  5. Step 5 — 回 GA4 後台開「報表 → 即時」,自己點一次網站。「過去 30 分鐘」有亮 1 就通了;標準報表要再等幾小時,不用慌。

7. 下一步:這篇本身就是一場公開實驗

說在前頭:這篇是 Lab 第一次「照 GSC 訊號補文」的實驗 — 從已經連 6 期有真實點擊的 csp 主題,往相鄰的搜尋需求擴,而不是憑感覺開新戰場。上線後我會盯 4 期週報,追蹤 csp 這組查詢的變體數有沒有從 5 個往外長、點擊有沒有跟上。結果不管好壞,都會寫在之後的週報裡。

如果你照這篇修好了自己的 GA4,下一步建議把 GSC 也串起來(裝好監視器才看得到搜尋端的數據),流程在 #3 那篇的後半。

名詞解釋

內容安全政策(CSP, Content Security Policy)
網站的白名單防火牆:只允許指定來源的程式跟資源執行,用來擋惡意注入。設太嚴會誤殺自己要用的工具。
指令(directive)
CSP 名單裡的一條規則欄位,例如 script-src 管「誰的程式可以執行」、connect-src 管「可以連線到誰」。
Console(主控台)
瀏覽器按 F12 打開的訊息區,網頁被擋掉、出錯都會在這裡印紅字,是除錯第一站。
一次性通行碼(nonce)
伺服器每次出頁面時生成的隨機字串,放進 CSP 後只有帶這個字串的程式能執行,比白名單更嚴格。靜態站通常做不到。
GTM(Google Tag Manager)
Google 的代碼管理工具:把 GA4、廣告追蹤等程式碼集中放進一個「容器」統一管理,不用逐頁改網站原始碼。
GA4(Google Analytics 4)
Google 的流量分析工具:訪客從哪來、看了什麼、停多久。GSC 管「搜尋結果上的表現」,GA4 管「進站後的行為」。
部署(deploy)
把做好的網站或程式「推上線」讓所有人用得到的動作。
Vercel
把網站免費發佈到網路上的服務:接上 GitHub 後,每次推程式碼就自動更新網站,個人專案免費方案就夠用。

看完這篇之前先確認:

適合你
  • GA4 裝了 console 一片紅、或即時報表永遠 0 的人
  • 自己在 vercel.json / nginx 鎖過 CSP header 的靜態站
  • 用 GTM 但預覽模式一直開不起來的人
不適合
  • WordPress 外掛全自動、從沒設過 CSP 的站(你大概率遇不到這題)
  • 還沒開始裝 GA4 的人(先看 #3 的安裝全流程)
  • 用 Plausible / Umami 等替代分析的站(排查方法可借,網域清單不同)
最常踩
  • 只開 googletagmanager 忘了 google-analytics — 載入正常、上報全滅(情境 2)
  • 改了 CSP 沒重新部署,以為沒修好又亂改一通
  • 想寫 google.* 偷懶 — CSP 不允許主機名右側萬用字元,每個頂級網域要逐一列(官方原話)

這篇是收斂後寫的版本。
我每兩週寄一封電子報,講「正在做但還沒寫成文章」的東西——
包含每月幫你過濾值得花時間的新 AI 工具,
以及 Lab 新文的個人版(你會比公開版早一週收到)。

→ 訂閱(雙週一封,第一封自動寄起步清單)

跳轉 Substack、隨時取消、不轉賣 email。

如果內容對你有用就太好了
隨喜斗內

Buy Me a Coffee at ko-fi.com
NEXT CHAPTER ▸ #3 GA4+GSC 安裝踩坑:28 頁 GA 一起悶掉的原始事件

相關閱讀

這篇背後的真實開發過程記錄在 Build Log搜尋標籤:cspga4gtmvercel

本篇為個人實驗紀錄。CSP 網域清單以 Google Tag Platform 官方文件為準(2026-07-17 查核),Google 端點可能隨時間變動;我的站只跑 gtag,情境 1、2 為親身除錯,情境 3(GTM)為官方文件整理。教育研究用途,不構成投資建議。

← 回 SEO 菜鳥成長史

⚠ 本站所有內容僅供教育與研究用途,不構成投資建議,不保證任何獲利。投資有風險,使用者須自行判斷並承擔結果。