TL;DR
- 我要的東西:一個自己的後端——存資料、發 token、跑邏輯,不要養機器、不要月費。
- 選的方案:Cloudflare Workers(跑邏輯)+ D1(SQLite 資料庫)+ Hono(路由框架),全部在免費方案內。
- AI 協作怎麼幫上忙:骨架、schema、WebCrypto 手刻的 PBKDF2/JWT、wrangler 指令——一個下午從零到線上。
- 免費額度(2026 數字,實測):Workers 每天 10 萬 requests;D1 每天讀 500 萬列、寫 10 萬列、總儲存 5GB。個人專案這額度幾乎用不完。
- 最值得記的坑:wrangler dev跟wrangler d1 execute --local用兩套不同的本地資料夾,本地測資料對不上不是你的 bug。
我有一個純靜態的部落格,想在它旁邊加一個「自己的後端」——能存資料、能驗身分、能跑邏輯,而且不想為它養一台 server、不想每個月被帳單追著跑。最後選了 Cloudflare Workers + D1,全程用 AI 協作把它從零架起來。
這篇不談「為什麼要後端」,只記三件具體的事:(1) 怎麼跟 AI 一起把 Workers + D1 的骨架在一個下午內搭好、部署上線;(2) 在 workerd 這個沒有 Node API 的環境裡,密碼雜湊跟 JWT 怎麼用 WebCrypto 手刻;(3) 最重要的——Cloudflare 免費方案的額度到底怎麼算,什麼時候會撞牆。
1. 我想要什麼
很單純:我想要一個自己的後端。
能收資料、能存進資料庫、能驗證身分發 token、能跑一點伺服器端邏輯——一個我完全掌握、資料在我手上的後端。但我有兩條紅線:不想為它養一台 server(不想 SSH 進去 apt update、不想顧 nginx、不想半夜被 OOM 叫醒),而且不想每個月被一筆固定帳單追著跑。理想狀態是:沒人用的時候它就是 0 成本,有人用的時候它自己醒來。
這就是這篇要解決的事——怎麼把這樣一個後端,用 AI 協作、在免費方案內、零維運地架起來。
這篇刻意只談「怎麼把它做出來」跟「免費額度怎麼算」,不展開「我為什麼需要後端」那條線。
2. 為什麼是 Cloudflare Workers + D1
我要的是「不養機器、零月費、自動 scale 到零」這個組合,符合的選項其實不多。Cloudflare 這套對得上:
| 我要的 | Cloudflare 怎麼給 |
|---|---|
| 跑伺服器端邏輯,不顧機器 | Workers:邊緣 serverless,沒請求就不計費,自己 scale to zero |
| 自己的資料庫,資料在我手上 | D1:Cloudflare 託管的 SQLite,跟 Workers 同生態,綁定即用 |
| 零月費起步 | 免費方案:Workers 每天 10 萬請求、D1 每天 500 萬讀,個人專案用不完 |
| 寫起來像寫一般 Web 後端 | Hono:極輕量路由框架,API 跟 Express 很像,在 Workers 上原生跑 |
3. AI 協作:一個下午把骨架架起來
整個後端 7 個檔、不到 500 行 TypeScript,是跟 AI 來回協作搭出來的。流程大致是:
第一步:讓 AI 出骨架。 我描述要的東西(會員註冊/登入、JWT、一張資料表、admin 看統計),AI 直接把 worker/ 子目錄的結構列出來——index.ts(Hono app + 路由)、auth.ts、crypto.ts、members.ts、admin.ts、middleware.ts、types.ts,加上 wrangler.toml 設定檔跟 D1 的 migration SQL。職責切乾淨,一個檔一件事。
worker/
├─ wrangler.toml # 設定:name、D1 binding、環境變數
├─ migrations/0001_init.sql
└─ src/
├─ index.ts # Hono app + 路由 + CORS
├─ crypto.ts # PBKDF2 + JWT(WebCrypto)
├─ auth.ts # register / login / me
├─ members.ts # 受保護內容 + 記錄
├─ admin.ts # 後台統計
└─ middleware.ts # 驗 JWT / CORS
第二步:wrangler 把它接上 Cloudflare。 wrangler 是 Cloudflare 的官方 CLI(這次用的是 4.104.0)。建資料庫、跑 migration、本地起 dev server、部署,全靠它:
npx wrangler login # 開瀏覽器授權(一次性)
npx wrangler d1 create bob-members # 建 D1,回傳一個 database_id
# 把 database_id 填進 wrangler.toml 的 [[d1_databases]]
npx wrangler d1 migrations apply bob-members --local # 本地建表
npx wrangler dev # 本地起 server,瀏覽器/curl 打 round-trip
npx wrangler d1 migrations apply bob-members --remote # 動線上 DB
npx wrangler deploy # 部署,拿到 *.workers.dev 網址
第三步:機密用 wrangler secret put,不進 git。 JWT 的簽章密鑰、admin token 這類東西,絕不寫進 wrangler.toml(那會進版控)。用:
npx wrangler secret put JWT_SECRET # 互動式貼值,存進 Cloudflare,程式用 env.JWT_SECRET 拿
npx wrangler secret put ADMIN_TOKEN
非機密的設定(像 CORS 白名單的允許來源)才放 wrangler.toml 的 [vars]。
AI 在這段最幫得上忙的,不是「幫我打字」,是把整套 wrangler 流程的順序跟坑一次講清楚——哪一步該先做、database_id 要填哪、secret 跟 vars 的界線在哪。少走很多回頭路。
4. workerd 沒有 Node:WebCrypto 手刻密碼與 JWT
這段是技術上最有意思的部分,也是 AI 協作真正省時間的地方。
Workers 跑在 Cloudflare 自家的 workerd runtime,它不是 Node.js——沒有 crypto 模組、沒有 bcrypt 這種現成套件可以 npm install 來雜湊密碼。能用的是瀏覽器標準的 WebCrypto API(crypto.subtle)。
所以密碼雜湊得自己用 PBKDF2 刻:
const PBKDF2_ITER = 100_000;
async function derive(password: string, salt: Uint8Array, iter: number) {
const key = await crypto.subtle.importKey('raw', enc.encode(password), 'PBKDF2', false, ['deriveBits']);
const bits = await crypto.subtle.deriveBits(
{ name: 'PBKDF2', salt, iterations: iter, hash: 'SHA-256' },
key, 256,
);
return bufToB64(bits);
}
這裡有個剛好對上的細節:workerd 限制 PBKDF2 迭代不能超過 10 萬次,而 10 萬次正好落在免費方案「每次呼叫 10ms CPU」的預算內跑得完。上限跟預算對齊,用 100k 剛剛好——這種「環境限制」的知識,正是問 AI 比自己踩一輪快的地方。
JWT 也一樣手刻——crypto.subtle.sign/verify 做 HS256 簽章,header / payload / signature 三段自己用 base64url 拼:
const data = ${header}.${body};
const sig = await crypto.subtle.sign('HMAC', key, enc.encode(data));
return ${data}.${b64url(bufToB64(sig))};
驗證密碼跟比對 token 都記得用常數時間比對(逐字元 XOR 累加),別用 ===——這種安全細節 AI 會主動提醒補上。
重點:在一個沒有 Node 生態的環境,「現成套件不能用」反而逼你理解底層在做什麼。AI 在這裡的價值是把 WebCrypto 那串又長又容易拼錯的 API 一次給對。
5. 免費額度到底怎麼算(這段最實用)
這是我最想講清楚的一段,因為「免費」不等於「無限」,撞牆的點要先知道。以下是 2026 年 Cloudflare 免費方案的實際數字。
Workers 免費方案
| 項目 | 免費額度 | 備註 |
|---|---|---|
| 請求數 | 每天 100,000 requests | UTC 午夜重置 |
| CPU 時間 | 每次呼叫 10ms | I/O 等待不算 CPU |
D1(資料庫)免費方案
| 項目 | 免費額度 | 撞牆會怎樣 |
|---|---|---|
| 讀取 | 每天 500 萬 rows read | 超過當天無法再查詢,API 回錯 |
| 寫入 | 每天 100,000 rows written | 超過當天無法寫入 |
| 儲存 | 總共 5 GB | 帳號內所有 DB 加總,滿了要先刪資料才能再寫 |
SELECT 掃 100 列就算 100 read,不是 1。所以真正要留意的是「有沒有寫出會掃全表的爛查詢」——加對索引、別 SELECT * 撈整張表,500 萬列/天 對小站綽綽有餘。
重置時間:免費額度每天 UTC 00:00 歸零(台灣時間早上 8 點)。撞牆是「當天」被擋,隔天自動恢復,不是永久鎖死。
一句話結論:對「個人專案規模」的後端,免費方案的天花板高到你正常用根本碰不到。會先撞到的通常不是請求數,是「不小心寫了個掃全表的查詢」把 read 數吃爆——這是程式問題,不是方案問題。
6. 三個真實踩坑
1. wrangler dev 跟 d1 execute --local 是兩套不同的本地資料夾(最坑)
本地開發時,我用 wrangler d1 execute --local 塞了測試資料進去,結果 wrangler dev 起的 server 怎麼查都查不到。不是程式錯——是這兩個指令在 wrangler v4 用了各自獨立的本地 persistence 目錄,你往 A 寫、B 讀不到。卡很久才發現。本地驗資料對不上時,先懷疑這個,別懷疑自己的 SQL。
2. CORS 白名單要比對「前端的 Origin」,不是後端網址
後端設 CORS 白名單時,要放的是會來打你 API 的前端網址(例如 https://yanchen.app),不是後端自己的網址。一開始把後端 *.workers.dev 填進白名單,瀏覽器一律 Failed to fetch——因為 CORS 檢查的是「請求從哪個 Origin 發出來」。
3. 機密一旦寫進 wrangler.toml 就回不去了
wrangler.toml 會進版控。JWT secret、admin token 這類東西只能走 wrangler secret put(存在 Cloudflare 端、程式用 env.X 拿)。寫錯地方等於把鑰匙 commit 進 git——AI 在這點會主動把你攔下來,但自己手動時很容易順手寫進設定檔。
7. 小結
我要的東西很簡單——一個自己的後端,不養機器、零月費。Cloudflare Workers + D1 + Hono 這套,用 AI 協作,一個下午就從零搭到線上,而且穩穩待在免費方案裡。
技術上最值得記的三件事:(1) workerd 沒有 Node,密碼跟 JWT 得用 WebCrypto 手刻,AI 在這把又臭又長的 API 一次給對;(2) 免費額度算的是「列數/請求數」,個人專案的天花板高到正常用碰不到,會先撞牆的是爛查詢不是方案;(3) 本地那個 dev vs execute --local 兩套資料夾的坑,不知道會卡到懷疑人生。
如果你也想要一個零成本、不用顧機器的後端,這套值得一試。