免費託管靜態網站: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 上只需要一份設定檔:

wrangler.jsoncjsonc
{
  "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 要明確寫出來(遷移指南(外部連結)):

wrangler.jsoncDiff
 {
   "name": "my-site",
   "compatibility_date": "2026-11-04",
-  "pages_build_output_dir": "./dist"
+  "assets": {
+    "directory": "./dist",
+    "not_found_handling": "404-page"
+  }
 }

兩者的部署流程大致如下:

Pages 與 Workers 的部署流程。靜態檔案請求兩邊都不收費;執行到 Functions 或 Worker 程式的請求計入每日額度。「Pages」:git push (GitHub / GitLab),接著 Pages 建置 (免費方案每月 500 次),接著 pages.dev 與自訂網域 (子網域可以留在外部 DNS)。「Workers + Static Assets」:git push (4 種 Git 平台),接著 Workers Builds (免費方案每月 3,000 分鐘),接著 workers.dev 與自訂網域 (網域必須在 Cloudflare 上)。最後匯集到「靜態檔案請求 (兩邊都免費、不限次數)」。git pushGitHub / GitLabPages 建置免費方案每月 500 次pages.dev 與自訂網域子網域可以留在外部 DNSgit push4 種 Git 平台Workers Builds免費方案每月 3,000 分鐘workers.dev 與自訂網域網域必須在 Cloudflare 上靜態檔案請求兩邊都免費、不限次數PagesWorkers + StaticAssetsPages 與 Workers 的部署流程。靜態檔案請求兩邊都不收費;執行到 Functions 或 Worker 程式的請求計入每日額度。「Pages」:git push (GitHub / GitLab),接著 Pages 建置 (免費方案每月 500 次),接著 pages.dev 與自訂網域 (子網域可以留在外部 DNS)。「Workers + Static Assets」:git push (4 種 Git 平台),接著 Workers Builds (免費方案每月 3,000 分鐘),接著 workers.dev 與自訂網域 (網域必須在 Cloudflare 上)。最後匯集到「靜態檔案請求 (兩邊都免費、不限次數)」。git pushGitHub / GitLabPages 建置免費方案每月 500 次pages.dev 與自訂網域子網域可以留在外部 DNSgit push4 種 Git 平台Workers Builds免費方案每月 3,000 分鐘workers.dev 與自訂網域網域必須在 Cloudflare 上靜態檔案請求兩邊都免費、不限次數PagesWorkers + Static Assets
Pages 與 Workers 的部署流程。靜態檔案請求兩邊都不收費;執行到 Functions 或 Worker 程式的請求計入每日額度。

兩邊都會用到的 _headers 檔案格式相同:建置後要出現在輸出資料夾(例如 dist/)的根目錄;用框架時通常放在 public/,建置時會複製過去。檔案裡第一行寫路徑,下面縮排寫標頭,最多 100 條規則,每行最多 2,000 個字元。它只套用在靜態檔案的回應上,Pages Functions 與 Worker 程式產生的回應要在程式裡自己加(Workers headers(外部連結)、Pages headers(外部連結))。

public/_headersText
/*
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin

/assets/*
  Cache-Control: public, max-age=31536000, immutable

範例裡的 /assets/* 要換成框架實際輸出帶雜湊檔名的資料夾。

免費方案比較表

項目(免費方案)PagesWorkers + Static Assets
靜態檔案請求免費、不限次數免費、不限次數
伺服器端程式的請求Pages Functions 計入 Workers 免費方案的每日額度每天 100,000 次,整個帳號共用(與 Pages Functions 共用)
檔案數每個網站 20,000 個每個 Worker 版本 20,000 個
單檔大小25 MiB25 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(外部連結))。

_routes.jsonJSON
{
  "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(外部連結))。

規模變大時的對照

需求PagesWorkers + Static Assets
API、表單處理Pages Functions(/functions 依檔名路由)Worker 程式(設定檔加 main)
排程觸發不支援免費方案每個帳號 5 個
資料庫D1、KV 等綁定;Durable Objects 要另建 WorkerD1、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(外部連結))。

兩邊都要注意的情況:

文件沒有寫的部分

Workers Builds 的 3,000 分鐘與 Pages 的 500 次建置用完之後會怎樣(擋下、排隊或收費),兩邊的文件都沒有寫。Pages 文件首頁(外部連結)寫的是「500 deploys per month」,限額頁(外部連結)寫的是 500 builds,也沒有說明直接上傳(外部連結)是否計入。

小結

  • 新的靜態網站、網域在 Cloudflare:用 Workers 加上 Static Assets。靜態檔案請求一樣免費,之後加程式、排程觸發或資料庫都不用換平台,也是官方建議的方向。
  • 網站放在子網域、DNS 不在 Cloudflare 也不打算移過來,或只需要零設定的分支預覽與拖拉上傳:用 Pages。
  • 已經在 Pages 上、只放靜態檔案:可以繼續用,等需要排程觸發、佇列消費者或 Workers Logs 時再照遷移指南搬到 Workers。

註腳

  1. 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 設定檔(設定)。

  2. 選「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。

  3. 文件提醒,沒有先在儀表板加入網域就手動建立 CNAME,網域會無法解析,可能出現 522 錯誤。

  4. 文件寫「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。

  5. 範圍可以選「Previews only」或「All traffic」,需要帳號已啟用 Zero Trust,不支援 WebSocket。這個功能在 2026 年 8 月 14 日推出,見更新紀錄;設定方式見 Cloudflare Access on Workers。

  6. 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。

這篇就到這裡,謝謝你讀完。

Read in English