免費託管靜態網站:Cloudflare Workers 還是 Pages?
以免費方案為前提,比較 Cloudflare Workers 與 Pages 託管靜態網站的利弊、擴充性,以及怎麼選。
要把一個前端靜態網站放到 Cloudflare 上、而且不想付錢時,會遇到兩個選項:Pages,以及加上 Static Assets 的 Workers。這篇筆記以免費方案為前提,比較兩者的額度、利弊,以及之後加上伺服器端程式、資料庫或改用付費方案時的差別,最後整理出可以直接對照的選擇條件。
文中的限額與價格以 2026 年 11 月的官方文件為準。
情境
網站經過建置後會得到一個資料夾(例如 dist/),裡面只有 HTML、CSS、JavaScript 和圖片,沒有需要在伺服器上執行的程式。目標是:用 Git 推送就自動部署、能接自訂網域、每個月不用付費。
兩個產品都做得到這些事。差別在於額度怎麼算、預覽怎麼設定、網域有什麼限制,以及網站變大之後還有多少空間。
各自是什麼
Cloudflare Pages
Pages(外部連結) 是 Cloudflare 專門託管網站的產品。常見做法是在儀表板(Dashboard)連上 GitHub 或 GitLab 的 repo,設定建置指令和輸出資料夾,之後每次推送都會自動建置、部署(Git integration(外部連結))。每次部署都有自己的 <hash>.<project>.pages.dev 網址,每個分支也有 <branch>.<project>.pages.dev 別名,不需要額外設定;分支別名會轉成小寫,非英數字元換成連字號,例如 fix/api 變成 fix-api(Preview deployments(外部連結))。
不想接 Git 時,可以用直接上傳(Direct Upload)(外部連結):在儀表板拖拉上傳最多 1,000 個檔案,或用 Wrangler1 上傳最多 20,000 個檔案,每個檔案最大 25 MiB。需要伺服器端程式時,把 Pages Functions 放在 /functions 資料夾,檔名決定路由,例如 /functions/fruits/apple.js 對應 /fruits/apple(Functions routing(外部連結))。
Workers 加上 Static Assets
Workers 是在 Cloudflare 邊緣節點執行程式的服務。Static Assets(外部連結) 讓靜態檔案跟 Worker 一起上傳、一起部署。
Workers Static Assets
請求路徑符合某個靜態檔案時,直接回傳該檔案,不執行 Worker 程式碼;找不到對應的檔案、也沒有 Worker 程式時,回 404。設定檔裡沒有 main(Worker 程式的進入點)時,整個網站就只有靜態檔案;官方的靜態網站範例(外部連結)設定檔也沒有 main。
用 Git 自動部署的部分由 Workers Builds(外部連結) 負責:連上 repo、設定建置指令,部署指令預設是 npx wrangler deploy(Builds configuration(外部連結)),推送到正式(production)分支就會建置並部署2。Workers Builds 可以連 Artifacts、GitHub、GitLab 與 Cursor Origin 的 repo,不支援自架的 GitHub 或 GitLab;其他平台(例如 Bitbucket)可以用外部的 CI/CD(例如 GitHub Actions)搭配 Wrangler 部署(Workers Builds Git integration(外部連結))。
一個純靜態網站在 Workers 上只需要一份設定檔:
{
"name": "my-site",
"compatibility_date": "2026-11-04",
// 沒有 "main":不執行任何 Worker 程式碼,全部由靜態檔案回應
"assets": {
"directory": "./dist",
// 找不到路徑時,回傳最近的 404.html,狀態碼 404
"not_found_handling": "404-page"
}
}not_found_handling 可以設成 "single-page-application"、"404-page" 或 "none",預設是 "none"(Wrangler 設定(外部連結))。從 Pages 搬過來的話,主要的改動是輸出資料夾的寫法;Pages 會自己判斷 404 與單頁應用(SPA)的行為,Workers 要明確寫出來(遷移指南(外部連結)):
{
"name": "my-site",
"compatibility_date": "2026-11-04",
- "pages_build_output_dir": "./dist"
+ "assets": {
+ "directory": "./dist",
+ "not_found_handling": "404-page"
+ }
}兩者的部署流程大致如下:
兩邊都會用到的 _headers 檔案格式相同:建置後要出現在輸出資料夾(例如 dist/)的根目錄;用框架時通常放在 public/,建置時會複製過去。檔案裡第一行寫路徑,下面縮排寫標頭,最多 100 條規則,每行最多 2,000 個字元。它只套用在靜態檔案的回應上,Pages Functions 與 Worker 程式產生的回應要在程式裡自己加(Workers headers(外部連結)、Pages headers(外部連結))。
/*
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
/assets/*
Cache-Control: public, max-age=31536000, immutable範例裡的 /assets/* 要換成框架實際輸出帶雜湊檔名的資料夾。
免費方案比較表
| 項目(免費方案) | Pages | Workers + Static Assets |
|---|---|---|
| 靜態檔案請求 | 免費、不限次數 | 免費、不限次數 |
| 伺服器端程式的請求 | Pages Functions 計入 Workers 免費方案的每日額度 | 每天 100,000 次,整個帳號共用(與 Pages Functions 共用) |
| 檔案數 | 每個網站 20,000 個 | 每個 Worker 版本 20,000 個 |
| 單檔大小 | 25 MiB | 25 MiB |
| 建置額度 | 每月 500 次建置 | Workers Builds 每月 3,000 分鐘 |
| 同時建置數 | 1 個(以帳號計) | 1 個(以帳號計) |
| 單次建置時限 | 20 分鐘 | 20 分鐘 |
| 每個帳號的數量 | 100 個專案 | 100 個 Worker |
| 自訂網域 | 每個專案 100 個;子網域可以留在外部 DNS(用 CNAME),根網域必須是 Cloudflare 上的網域區域(zone) | 網域必須是 Cloudflare 上的 zone;每個 zone 100 個(以 zone 計,不是以專案計) |
| 預覽 | 每次部署與每個分支自動產生,數量不限 | Worker Previews,每個 Worker 100 個,要另外設定 |
| 排程觸發(Cron Triggers) | 不支援 | 每個帳號 5 個 |
| 記錄 | 即時記錄(Real-time logs) | 即時記錄、Workers Logs(每天 200,000 筆,保留 3 天) |
數字來源:Pages limits(外部連結)、Pages custom domains(外部連結)、Pages Functions pricing(外部連結)、Workers limits(外部連結)、Workers Builds limits(外部連結)、Worker Previews(外部連結)、Workers custom domains(外部連結)、Workers pricing(外部連結);功能是否支援來自遷移指南的對照表(外部連結)。
靜態檔案請求不計費
兩邊的文件都寫靜態檔案請求「free and unlimited」(Pages Functions pricing(外部連結)、Workers pricing(外部連結)、Static Assets billing and limitations(外部連結))。官方文件沒有逐字寫出「只回靜態檔的請求不計入每天 100,000 次」,但 Pages 的文件把「沒有執行 Functions 的請求」定義為靜態請求,Workers 的文件也寫只有執行到 Worker 程式的請求才計費。純靜態網站因此通常碰不到每日額度。
利弊與擴充性
以下都以免費方案為前提,額度數字見上方比較表。
Pages
- 優點:分支與每次部署的預覽網址自動產生,不用寫任何設定;可以在儀表板直接拖拉上傳一個資料夾就上線;網站放在子網域(例如
www.example.com)時,網域的 DNS 可以留在其他服務商,用 CNAME 指過來;根網域(例如example.com)則一樣要加成 Cloudflare 上的 zone,並把名稱伺服器(nameserver)改成 Cloudflare 的(Pages custom domains(外部連結))3;遷移指南的對照表(外部連結)裡,外部網域是唯一一項 Pages 支援、Workers 不支援的功能,另外還有四項(Early Hints、分支部署控制(Branch Deploy Controls)、依檔名路由、Pages Plugins)在 Workers 上只部分支援;404 與 SPA 的行為會自動判斷;儀表板使用者人數不限(Pages limits(外部連結))。 - 缺點:建置額度按次數計算,不論建置花多久,每次推送都算一次;Git 整合(外部連結)只支援 GitHub 與 GitLab,不含自架版本,其他平台要在 CI 裡用直接上傳;Git 整合和直接上傳建立的專案之後不能互換(Direct Upload(外部連結)、Git integration(外部連結)),但 Git 整合的專案可以用分支控制暫停自動部署,改用 Wrangler 直接部署(Git integration(外部連結));預覽網址預設公開;開啟「Enable access policy」後,預設只有 Cloudflare 帳號的成員能看,可以再用 Access 原則(policy)加入其他人。這個設定只保護預覽,正式網址(
*.pages.dev)與自訂網域要另外照文件的 Known issues 手動設定 Access4;官方文件建議新專案改用 Workers(外部連結),Cloudflare 也在部落格(外部連結)表示之後的投入、最佳化與新功能都放在 Workers。 - 擴充時:加 API 或表單處理時,在
/functions放 Pages Functions,它的請求計入 Workers 免費方案的每日額度,計費方式也跟 Workers 相同(Pages Functions pricing(外部連結))。資料庫可以用 D1、KV 等綁定(bindings),但 Durable Objects 不能在 Pages 專案裡建立,要另外部署一個 Worker 再綁進來(Pages Functions bindings(外部連結))。排程觸發、佇列消費者(Queue consumers)、Workers Logs、Logpush 都不支援(遷移指南(外部連結))。檔案超過 20,000 個時,要改用 Pro、Business 或 Enterprise 方案,並在專案設定PAGES_WRANGLER_MAJOR_VERSION=4,上限才會變成每個網站 100,000 個;這些方案的建置次數也比較多,Pro 每月 5,000 次、Business 每月 20,000 次(Pages limits(外部連結))。Pages 的限額頁沒有提到 Workers 付費方案會提高這個上限。需要這些功能時,官方提供從 Pages 搬到 Workers 的指南(外部連結)。
加了 Functions 之後,用 _routes.json 限定範圍
專案有 functions 資料夾時,Pages 會在部署時自動產生 _routes.json,決定哪些請求要執行 Functions。手動寫的話,可以只讓 /api/* 執行程式碼,其餘請求維持免費的靜態檔案;沒有列在 include、或被 exclude 排除的路徑,不會執行 Functions。_routes.json 至少要有一條 include,include 與 exclude 合計最多 100 條,每條最多 100 個字元,exclude 優先(Functions routing(外部連結))。
{
"version": 1,
"include": ["/api/*"],
"exclude": []
}Workers 加上 Static Assets
- 優點:建置額度按分鐘算,建置時間短的網站可以建置很多次;設定集中在
wrangler.jsonc,可以跟程式碼一起版本控制;同一個專案之後要加伺服器端程式、排程觸發或佇列都不用換平台;在 Worker 的 Access 分頁開啟「Protect this Worker behind Access」並把範圍選成「All traffic」,一個設定就保護這個 Worker 的所有網址,包含路由、自訂網域、workers.dev與預覽網址5;這是 Cloudflare 建議新專案使用的方式(外部連結)。 - 缺點:自訂網域必須是 Cloudflare 上的 zone(文件寫需要「An active Cloudflare zone」),也就是網域的名稱伺服器要交給 Cloudflare 管理,子網域也一樣(Workers custom domains(外部連結)、遷移指南(外部連結));分支預覽要自己設定 Worker Previews,預覽網址預設公開6;
workers.dev路由與版本網址(Version URLs)在開啟時是公開的,見下方說明;帶Range標頭的請求會拿到完整檔案的 200 OK,而不是 206 Partial Content,Safari 播放影片這類用法可能會出問題,官方的替代做法是用run_worker_first搭配env.ASSETS.fetch()(Static Assets billing and limitations(外部連結))。 - 擴充時:加 API 或表單處理時,在設定檔加上
main寫 Worker 程式,請求仍然先找靜態檔案,找不到才執行程式;執行到程式的請求計入每天 100,000 次的額度,每次請求的 CPU 時間上限是 10 毫秒,超過每日額度會回 Error 1027,額度在 UTC 午夜重設;每個路由可以設定超過額度時直接略過 Worker(fail open)或顯示 1027 錯誤頁(fail closed)(Workers limits(外部連結))。資料庫與其他服務在免費方案就能用:D1(外部連結) 每天可讀 500 萬列、寫 10 萬列,總容量 5 GB,達到每日讀寫上限後無法查詢,UTC 00:00 重設;Durable Objects(外部連結) 只能用 SQLite 後端,每天 100,000 次請求、13,000 GB-s,每天讀 500 萬列、寫 10 萬列,總容量 5 GB,超過時操作會失敗;Queues(外部連結) 每天 10,000 次操作。檔案超過 20,000 個,或執行程式的請求每天超過 100,000 次時,改用 Workers 付費方案(每個帳號每月最低 5 美元),檔案上限變成每個版本 100,000 個,請求不再有每日上限(Workers pricing(外部連結)、Workers limits(外部連結))。
關掉 workers.dev 之後,版本網址會不會跟著關
workers.dev 頁(外部連結)說關掉 workers.dev 路由不會關掉版本網址;Version URLs 頁(外部連結)則說版本網址的預設值跟著 workers_dev 走(「If workers_dev is disabled, Version URLs are disabled by default」),而設定檔沒有 preview_urls 時,Wrangler 不會改動既有的設定。因此建議在設定檔明確寫出 preview_urls,不要依賴預設值。遷移指南(外部連結)設定 Worker Previews 的範例是 "preview_urls": true 搭配 previews 區塊。
run_worker_first 的路徑會計入額度
設定 assets.run_worker_first 之後,符合的路徑一定會先執行 Worker。這個欄位可以是布林值或路由模式的陣列(支援 ! 排除,最多 100 條),預設 false(Wrangler 設定(外部連結))。免費方案的每日額度用完時,這些請求會回 429,不會改回傳靜態檔案;不符合的路徑和用 !/... 排除的路徑不受影響(Static Assets billing and limitations(外部連結))。
規模變大時的對照
| 需求 | Pages | Workers + Static Assets |
|---|---|---|
| API、表單處理 | Pages Functions(/functions 依檔名路由) | Worker 程式(設定檔加 main) |
| 排程觸發 | 不支援 | 免費方案每個帳號 5 個 |
| 資料庫 | D1、KV 等綁定;Durable Objects 要另建 Worker | D1、KV、Durable Objects 都能直接用 |
| 佇列 | 只能當生產者(producer) | 生產者與消費者都支援;Workers 付費方案每月含 100 萬次操作,超過的部分每 100 萬次 0.40 美元 |
| 記錄 | 即時記錄 | 另有 Workers Logs、Logpush、Tail Workers、Source Maps;Workers Logs 自 2026 年 12 月 1 日起改用 Cloudflare Observability 的計價方式 |
| 檔案數 | Pro、Business、Enterprise 方案設定環境變數後每個網站 100,000 個 | Workers 付費方案每個版本 100,000 個 |
| 改用付費方案 | Functions 按 Workers 價格計費;檔案數與建置次數要改用 Pro 以上方案才會提高 | 每月最低 5 美元,含 1,000 萬次請求與 3,000 萬 CPU 毫秒;超過的部分每 100 萬次請求 0.30 美元、每 100 萬 CPU 毫秒 0.02 美元,不收流量費用 |
功能支援的來源是遷移指南(外部連結)與 Pages Functions bindings(外部連結),Pages 各方案的上限見 Pages limits(外部連結),Workers 的價格與記錄計價見 Workers pricing(外部連結) 與 Workers limits(外部連結),佇列價格見 Queues pricing(外部連結)。
Pages 繼續支援,新功能放在 Workers
Cloudflare 在 2025 年 4 月 8 日的部落格文章(外部連結)說 Pages 會繼續支援,但之後的投入、最佳化與新功能都放在 Workers。Pages 文件首頁(外部連結)有一段「Are you sure you want to use Pages?」,提示框寫著「Start new projects with Workers」;Workers Best Practices(外部連結) 寫「If you are starting a new project, use Workers instead of Pages」,並把 Static Assets 稱為部署靜態網站的建議方式。文章與文件都沒有公布 Pages 停止服務的日期。
怎麼選
以下幾種情況會考慮 Pages:
- 網站放在子網域(例如
www.example.com),網域的 DNS 不在 Cloudflare,也不打算把名稱伺服器移過來。根網域在 Pages 上一樣要是 Cloudflare 的 zone。 - 每個分支、每次部署都要有預覽網址,而且不想寫設定檔。
- 想在儀表板拖拉上傳一個資料夾就上線,檔案不超過 1,000 個。
- 已經有運作中的 Pages 專案,沒有用到排程觸發、佇列消費者、Workers Logs 這類只有 Workers 有的功能。
以下幾種情況會考慮 Workers 加上 Static Assets:
- 新專案,網域已經在 Cloudflare 上。
- 每月推送觸發的建置會超過 500 次:Workers Builds 按分鐘算,每次建置 2 分鐘的話,3,000 分鐘大約可以建置 1,500 次。
- 之後要加排程觸發、佇列消費者或 Durable Objects,或是需要 Workers Logs 查錯。
- 要用 Cloudflare Access 保護網站的所有網址(包含正式網址與自訂網域),而不只是預覽網址:Workers 在 Worker 層級開啟 Access 並選「All traffic」,一個設定就保護整個 Worker,不論從哪個網址進來(Cloudflare Access on Workers(外部連結));Zero Trust 免費方案(外部連結)最多 50 個使用者。Pages 也做得到,但正式網址要修改自動建立的 Access 應用程式,自訂網域要另外建立 Access 應用程式(Known issues(外部連結))。
兩邊都要注意的情況:
- 檔案數接近 20,000 個:兩邊免費方案的上限相同,但要超過時改用的方案不同,Pages 要改用 Pro 以上方案,Workers 要改用 Workers 付費方案(Pages limits(外部連結)、Workers limits(外部連結))。
- 伺服器端程式的請求每天會超過 100,000 次:Pages Functions 與 Workers 共用同一個額度,換平台不會多出額度(Pages Functions pricing(外部連結))。
- 選 Workers、而網站有影片要在 Safari 播放:Workers 的靜態檔案不回 206 Partial Content,要用
run_worker_first讓這些路徑執行 Worker 程式來處理Range請求;這些請求會執行 Worker,免費方案超過每日額度時會回 429(Static Assets billing and limitations(外部連結))。
文件沒有寫的部分
Workers Builds 的 3,000 分鐘與 Pages 的 500 次建置用完之後會怎樣(擋下、排隊或收費),兩邊的文件都沒有寫。Pages 文件首頁(外部連結)寫的是「500 deploys per month」,限額頁(外部連結)寫的是 500 builds,也沒有說明直接上傳(外部連結)是否計入。
小結
- 新的靜態網站、網域在 Cloudflare:用 Workers 加上 Static Assets。靜態檔案請求一樣免費,之後加程式、排程觸發或資料庫都不用換平台,也是官方建議的方向。
- 網站放在子網域、DNS 不在 Cloudflare 也不打算移過來,或只需要零設定的分支預覽與拖拉上傳:用 Pages。
- 已經在 Pages 上、只放靜態檔案:可以繼續用,等需要排程觸發、佇列消費者或 Workers Logs 時再照遷移指南搬到 Workers。
註腳
-
Wrangler 是 Cloudflare 開發者平台(Developer Platform)的命令列工具(CLI),用來管理 Workers 專案;官方建議裝在各專案裡(
npm i -D wrangler@latest),不要全域安裝(安裝)。wrangler dev在本機啟動開發伺服器,wrangler deploy把 Worker 部署到 Cloudflare(Workers 指令);wrangler pages deploy把一個靜態檔案資料夾部署成一次 Pages 部署(Pages 指令)。設定檔可以是 JSON(wrangler.json、wrangler.jsonc)或 TOML(wrangler.toml),官方建議新專案用wrangler.jsonc,部分較新的功能只支援 JSON 設定檔(設定)。 -
選「Create new token」時,Workers Builds 會自動建立一個 API token,之後可以在 My Profile > API Tokens 調整權限;預設權限包含 Account Settings 讀取、Workers Scripts 編輯、Workers KV Storage 編輯、Workers R2 Storage 編輯、所有 zone 的 Workers Routes 編輯,以及 User Details 與 Memberships 讀取。見 Builds configuration。儀表板上的 Worker 名稱要跟設定檔的
name一致,見 Builds troubleshooting。 -
文件寫「By default, these deployment URLs are public」,並說開啟存取原則「will only protect your preview deployments」,見 Preview deployments。保護
*.pages.dev要修改自動建立的 Access 應用程式,自訂網域要在 Zero Trust 另外建立一個 self-hosted Access 應用程式,並把網域加為 public hostname,步驟見 Known issues。 -
範圍可以選「Previews only」或「All traffic」,需要帳號已啟用 Zero Trust,不支援 WebSocket。這個功能在 2026 年 8 月 14 日推出,見更新紀錄;設定方式見 Cloudflare Access on Workers。
-
Worker Previews 在 2026 年 9 月 22 日推出(見更新紀錄),需要 Wrangler 4.135.0 以上,用
npx wrangler preview建立;設定檔需要previews區塊(可以是空的),預覽不會繼承正式環境的變數、密鑰與綁定。Workers Builds 的預覽建置可以在 Settings > Build > Branch control 的「Enable Preview Builds」開關。見 Worker Previews、設定、Build branches。