<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Glue-Layer on Tarragon</title><link>https://tarrragon.github.io/blog/tags/glue-layer/</link><description>Recent content in Glue-Layer on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 06 Jul 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/glue-layer/index.xml" rel="self" type="application/rss+xml"/><item><title>靜態站的能力邊界與膠水層</title><link>https://tarrragon.github.io/blog/automation/00-mental-model/static-site-and-glue-layer/</link><pubDate>Mon, 06 Jul 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/automation/00-mental-model/static-site-and-glue-layer/</guid><description>&lt;p>靜態站的能力邊界是一條很硬的線：使用者的瀏覽器把 HTML/CSS/JS 抓下來之後，所有程式碼都在&lt;strong>使用者那一端&lt;/strong>執行，沒有任何一行程式跑在你控制的機器上。GitHub Pages、Netlify、Cloudflare Pages 這類託管都是把檔案原封不動送給瀏覽器，中間沒有一個「屬於你、會執行邏輯、看得到每個請求」的伺服器。這條線決定了靜態站能做什麼、不能做什麼。&lt;/p>
&lt;h2 id="為什麼靜態站量不到自己的流量">為什麼靜態站量不到自己的流量&lt;/h2>
&lt;p>流量統計的本質是「把每一次瀏覽記在某個你能事後查詢的地方」。傳統有伺服器的網站天生做得到，因為每個請求都會經過你的伺服器，伺服器在回應頁面的同時，順手在 access log 寫下一行「誰、什麼時候、看了哪一頁」。這行 log 是伺服器端的副產品，不需要前端配合。&lt;/p>
&lt;p>靜態站沒有這個副產品。GitHub Pages 確實有伺服器在送檔案，但那是 GitHub 的伺服器、不是你的——你拿不到它的 access log，也不能在它上面跑任何統計邏輯。所以對靜態站來說，「有人來看過」這個事實，在預設情況下沒有留在任何你查得到的地方。頁面被看完、瀏覽器關掉，紀錄就消失了。&lt;/p>
&lt;p>要把這個事實留下來，唯一的切入點是&lt;strong>頁面裡的 JavaScript&lt;/strong>——那是靜態站上唯一會執行的程式碼。做法是讓這段 JS 在頁面載入時，主動送一個請求到一個由你掌握的接收端，接收端把這次瀏覽記下來。這種「瀏覽器主動回報一則事件」的請求，慣例上叫做 &lt;strong>beacon&lt;/strong>。&lt;/p>
&lt;h2 id="膠水層補的是哪一塊">膠水層補的是哪一塊&lt;/h2>
&lt;p>膠水層（glue layer）是一段掛在別人免費平台上、只在被呼叫時才執行的伺服器端邏輯，用來補上靜態站缺的那一小塊伺服器能力。它的形態是一個函式，而非一台你要維護的主機：平時不佔資源、不計費，有請求打進來時才醒過來跑幾百毫秒，跑完就休眠。&lt;/p>
&lt;p>用流量統計來看這個分工會很清楚：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>靜態站（瀏覽器端）&lt;/strong>：負責偵測「這一頁被看了」，並發出 beacon。這段程式碼在使用者瀏覽器跑。&lt;/li>
&lt;li>&lt;strong>膠水層（伺服器端函式）&lt;/strong>：負責接住 beacon，把這次瀏覽寫進某個儲存體。這段程式碼在免費平台跑，是你控制的接收端。&lt;/li>
&lt;li>&lt;strong>儲存體&lt;/strong>：真正記住資料的地方。可以是一張 Google Sheet、一個免費資料庫、或平台自帶的 key-value 儲存。&lt;/li>
&lt;/ul>
&lt;p>膠水層補的就是中間那一塊——一個「屬於你、會執行、看得到每個 beacon」的接收端。它不必是完整後端，只要能接住請求、寫一筆資料就夠了。本指南模組二用 Google Apps Script 當這個膠水層，模組三用 Google Sheet 當儲存體。&lt;/p>
&lt;h2 id="client-beacon-架構怎麼運作">client beacon 架構怎麼運作&lt;/h2>
&lt;p>一次完整的流量紀錄走三步，全部由瀏覽器發起：&lt;/p>
&lt;ol>
&lt;li>使用者打開你的一篇文章，瀏覽器載入頁面，頁面裡的 JS 開始執行。&lt;/li>
&lt;li>JS 組出一則事件（例如「路徑 &lt;code>/posts/foo/&lt;/code>、時間、referrer」），送一個 HTTP 請求到膠水層的網址。&lt;/li>
&lt;li>膠水層收到請求，把這則事件 append 進儲存體，回一個簡短回應。瀏覽器不需要等這個回應、也不需要用它做任何事。&lt;/li>
&lt;/ol>
&lt;p>第三步的「不需要等回應」是 beacon 跟一般 API 呼叫最重要的差別。使用者是來讀文章的，不是來等統計寫完的——beacon 應該是 fire-and-forget（送出就忘）：發出去、不阻塞頁面、不管有沒有成功都不影響閱讀體驗。瀏覽器有一個專門為此設計的 API &lt;code>navigator.sendBeacon&lt;/code>，它保證即使使用者馬上關頁面，這個請求也會在背景送完。模組二會用到它。&lt;/p>
&lt;p>這個架構有一個取捨要先知道：beacon 只記得到「會執行 JS 的訪客」。爬蟲、關掉 JavaScript 的人、在 beacon 送出前就離開的人，都不會被算進去。因為紀錄的觸發點在瀏覽器端的 JS，client beacon 量到的數字&lt;strong>偏保守&lt;/strong>——它少算，但不會多算。對個人 blog 想知道「哪篇文章有人看」這個目的，偏保守完全夠用；但如果哪天需要精確到不能漏一個請求（例如計費），就得回到有伺服器 access log 的架構。判斷訊號很簡單：&lt;strong>漏算幾個訪客會不會造成實際損失&lt;/strong>——不會，就用 beacon；會，就別用。&lt;/p>
&lt;h2 id="下一步">下一步&lt;/h2>
&lt;p>beacon 該送到哪、那個接收端能承受多大的量、免費到什麼程度會開始要錢——這些是&lt;a href="https://tarrragon.github.io/blog/automation/00-mental-model/free-tier-and-tool-choice/" data-link-title="免費額度的思考方式與工具選型" data-link-desc="判斷免費膠水層撐不撐得住自己流量時該看哪個限制、以及 Apps Script 與 Cloudflare Workers 各自適合什麼場景">免費額度的思考方式與工具選型&lt;/a>要回答的。想直接把 beacon 做出來，跳到&lt;a href="https://tarrragon.github.io/blog/automation/02-analytics-beacon/" data-link-title="模組二：流量 beacon 實作" data-link-desc="把「頁面被看了就送一則事件、接收端寫進 Sheet」從零做到收到第一筆真實瀏覽紀錄時的完整實作">模組二：流量 beacon 實作&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>靜態站的能力邊界是一條很硬的線：使用者的瀏覽器把 HTML/CSS/JS 抓下來之後，所有程式碼都在<strong>使用者那一端</strong>執行，沒有任何一行程式跑在你控制的機器上。GitHub Pages、Netlify、Cloudflare Pages 這類託管都是把檔案原封不動送給瀏覽器，中間沒有一個「屬於你、會執行邏輯、看得到每個請求」的伺服器。這條線決定了靜態站能做什麼、不能做什麼。</p>
<h2 id="為什麼靜態站量不到自己的流量">為什麼靜態站量不到自己的流量</h2>
<p>流量統計的本質是「把每一次瀏覽記在某個你能事後查詢的地方」。傳統有伺服器的網站天生做得到，因為每個請求都會經過你的伺服器，伺服器在回應頁面的同時，順手在 access log 寫下一行「誰、什麼時候、看了哪一頁」。這行 log 是伺服器端的副產品，不需要前端配合。</p>
<p>靜態站沒有這個副產品。GitHub Pages 確實有伺服器在送檔案，但那是 GitHub 的伺服器、不是你的——你拿不到它的 access log，也不能在它上面跑任何統計邏輯。所以對靜態站來說，「有人來看過」這個事實，在預設情況下沒有留在任何你查得到的地方。頁面被看完、瀏覽器關掉，紀錄就消失了。</p>
<p>要把這個事實留下來，唯一的切入點是<strong>頁面裡的 JavaScript</strong>——那是靜態站上唯一會執行的程式碼。做法是讓這段 JS 在頁面載入時，主動送一個請求到一個由你掌握的接收端，接收端把這次瀏覽記下來。這種「瀏覽器主動回報一則事件」的請求，慣例上叫做 <strong>beacon</strong>。</p>
<h2 id="膠水層補的是哪一塊">膠水層補的是哪一塊</h2>
<p>膠水層（glue layer）是一段掛在別人免費平台上、只在被呼叫時才執行的伺服器端邏輯，用來補上靜態站缺的那一小塊伺服器能力。它的形態是一個函式，而非一台你要維護的主機：平時不佔資源、不計費，有請求打進來時才醒過來跑幾百毫秒，跑完就休眠。</p>
<p>用流量統計來看這個分工會很清楚：</p>
<ul>
<li><strong>靜態站（瀏覽器端）</strong>：負責偵測「這一頁被看了」，並發出 beacon。這段程式碼在使用者瀏覽器跑。</li>
<li><strong>膠水層（伺服器端函式）</strong>：負責接住 beacon，把這次瀏覽寫進某個儲存體。這段程式碼在免費平台跑，是你控制的接收端。</li>
<li><strong>儲存體</strong>：真正記住資料的地方。可以是一張 Google Sheet、一個免費資料庫、或平台自帶的 key-value 儲存。</li>
</ul>
<p>膠水層補的就是中間那一塊——一個「屬於你、會執行、看得到每個 beacon」的接收端。它不必是完整後端，只要能接住請求、寫一筆資料就夠了。本指南模組二用 Google Apps Script 當這個膠水層，模組三用 Google Sheet 當儲存體。</p>
<h2 id="client-beacon-架構怎麼運作">client beacon 架構怎麼運作</h2>
<p>一次完整的流量紀錄走三步，全部由瀏覽器發起：</p>
<ol>
<li>使用者打開你的一篇文章，瀏覽器載入頁面，頁面裡的 JS 開始執行。</li>
<li>JS 組出一則事件（例如「路徑 <code>/posts/foo/</code>、時間、referrer」），送一個 HTTP 請求到膠水層的網址。</li>
<li>膠水層收到請求，把這則事件 append 進儲存體，回一個簡短回應。瀏覽器不需要等這個回應、也不需要用它做任何事。</li>
</ol>
<p>第三步的「不需要等回應」是 beacon 跟一般 API 呼叫最重要的差別。使用者是來讀文章的，不是來等統計寫完的——beacon 應該是 fire-and-forget（送出就忘）：發出去、不阻塞頁面、不管有沒有成功都不影響閱讀體驗。瀏覽器有一個專門為此設計的 API <code>navigator.sendBeacon</code>，它保證即使使用者馬上關頁面，這個請求也會在背景送完。模組二會用到它。</p>
<p>這個架構有一個取捨要先知道：beacon 只記得到「會執行 JS 的訪客」。爬蟲、關掉 JavaScript 的人、在 beacon 送出前就離開的人，都不會被算進去。因為紀錄的觸發點在瀏覽器端的 JS，client beacon 量到的數字<strong>偏保守</strong>——它少算，但不會多算。對個人 blog 想知道「哪篇文章有人看」這個目的，偏保守完全夠用；但如果哪天需要精確到不能漏一個請求（例如計費），就得回到有伺服器 access log 的架構。判斷訊號很簡單：<strong>漏算幾個訪客會不會造成實際損失</strong>——不會，就用 beacon；會，就別用。</p>
<h2 id="下一步">下一步</h2>
<p>beacon 該送到哪、那個接收端能承受多大的量、免費到什麼程度會開始要錢——這些是<a href="/blog/automation/00-mental-model/free-tier-and-tool-choice/" data-link-title="免費額度的思考方式與工具選型" data-link-desc="判斷免費膠水層撐不撐得住自己流量時該看哪個限制、以及 Apps Script 與 Cloudflare Workers 各自適合什麼場景">免費額度的思考方式與工具選型</a>要回答的。想直接把 beacon 做出來，跳到<a href="/blog/automation/02-analytics-beacon/" data-link-title="模組二：流量 beacon 實作" data-link-desc="把「頁面被看了就送一則事件、接收端寫進 Sheet」從零做到收到第一筆真實瀏覽紀錄時的完整實作">模組二：流量 beacon 實作</a>。</p>
]]></content:encoded></item></channel></rss>