快速回答:給託管在 GitHub Pages、Netlify、Vercel 或 Cloudflare Pages 的任意網站接上能收資料的聯絡表單——一個 action 位址搞定,無伺服器、無資料庫、免費。
頁面一個下午就做好了,推到 GitHub Pages 或 Netlify 上,效果很漂亮——直到有人在聯絡表單裡點了「送出」,然後什麼都沒有發生。頁面只是檔案,靜態託管只會發檔案;表單的 POST 需要一個落點,而「落點」恰恰是靜態託管給不了的東西。
這裡給出與平台無關的解法:網站的每個位元組都維持靜態,只把表單的 action 指向一個替你存提交的託管端點。一行 HTML,在任何宿主上都一樣。
靜態託管替你補不了的那一塊
幾家主流宿主對這個缺口的處理各不相同,而差別裡全是坑:
- GitHub Pages —— 完全不管表單。
action必須指向站外,沒有第二條路。 - Netlify ——
data-netlify="true"在建構期擷取表單。功能是真的,但只在留在 Netlify 時成立:哪天搬家,收下來的提交和垃圾過濾全留在原地。 - Vercel —— 靜態檔案免費;想接住一個 POST,得自己寫並部署一個 serverless 函式。
- Cloudflare Pages —— 同樣:不上 Worker,表單就沒有去處。
四個選項裡三個把你的資料焊死在一個平台上,剩下一個要你寫伺服器端程式碼。第四個才是一行走到哪裡都能用的 URL。
兩分鐘接好
在 FormLM 上發布任意表單(哪怕一張空白採集表),你就得到一個端點:https://formlm.me/api/v3/share/<token>/form。把現成的 HTML 表單指過去:
<form action="https://formlm.me/api/v3/share/YOUR_TOKEN/form" method="POST"> <input name="name" placeholder="您的稱呼" required> <input name="email" type="email" placeholder="Email" required> <textarea name="message" placeholder="想聊點什麼?" required></textarea> <!-- 蜜罐:CSS 藏起來,機器人會填,真人看不見 --> <input name="company" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px"> <button type="submit">送出</button> </form>
整合到此為止:沒有建置步驟,倉庫裡不用藏任何金鑰,也沒有函式要部署。name 屬性就是存下來的欄位——今天加一個輸入框,明天的提交就帶著新欄位。想讓使用者留在頁內?把原生送出換成對同一個端點 JSON 側的幾行 fetch,就地顯示成功提示;儲存的行為完全一致。
上線前先驗一發
端點就是普通 HTTP,整條鏈路可以在終端機裡先跑通——不用瀏覽器,不用先部署:
curl -X POST "https://formlm.me/api/v3/share/YOUR_TOKEN/form" \ -d "name=冒煙測試&email=me@example.com&message=hello" curl "https://formlm.me/api/v3/share/YOUR_TOKEN/query?page=1&size=10"
記錄以 JSON 返回;控制台裡的資料介面把同樣的提交做成人類可讀的收件匣,CSV 匯出一步到位。翻頁迴圈、聚合彙整、排程匯出這些長尾玩法,在《把表單資料交給程式:Query、Summary 與 CSV 工作流》裡展開講。
另外幾條路為什麼都不順手
mailto:—— 開啟訪客的郵件客戶端(如果他還留著),順便把信箱地址送給全網每一個爬蟲。這是 1998 年的方案。- 內嵌 iframe 表單 —— 拖進來最快,但樣式是別人的、品牌露出是別人的,你剛調好的頁面版面也會被它攪亂。
- 自己寫函式 —— 一個收 POST 的 serverless 函式確實不難;難的是圍著它補的郵件管線、垃圾過濾、儀表板、匯出和可用性兜底。
- 託管端點 —— 標記語言歸你,網站維持靜態,儲存、防垃圾、取數歸別人。這就是本文推薦的這筆交易。
"「靜態網站」描述的是頁面怎麼伺服,不是你的資料非得有多寒酸。離一個真收件匣,表單只差九個字元的 action——宿主照舊,讓那行 URL 當後端。"
🛠️ 今晚就把聯絡表單上線
一個免費端點包下全部工作——整個方案裡沒有一台伺服器:
- 接受原生 HTML POST —— GitHub Pages、Netlify、Vercel、Cloudflare Pages 或任何宿主都能用
- 免費方案 —— 發布表單和收取提交都不設按次計費
- 收件匣 + 查詢 + 彙整 + CSV —— 讀的一側隨寫的一側一起交付
- 防濫用 —— 端點級頻率限制,加上讓垃圾提交一眼可辨的蜜罐寫法
✅ 重點回顧
- 靜態宿主只發檔案;表單 POST 需要落點,四家主流宿主裡只有 Netlify 給了一個——還把它焊在平台上
- 託管表單端點把「收提交」縮成一個 action URL,在所有宿主上通用
- 欄位來自你的
name屬性——輸入框隨便加,不存在資料表結構遷移 - 部署前用 curl 驗鏈路;上線後在資料介面、查詢端點或 CSV 裡取數
- 藏一個蜜罐輸入框:帶值的提交就是機器人流量,讀取時一眼識破、隨手過濾
- 網站繼續靜態——只是資料不再無家可歸
常見問題
GitHub Pages 能處理表單提交嗎?
不能。GitHub Pages 只伺服靜態檔案,頁面裡的 POST 發出去沒有落點。解法只有一行:把表單的 action 指向一個託管端點,例如 FormLM Data API。頁面維持純靜態,提交存進伺服器端,隨時能翻、能查、能匯出。
我一直在用 Netlify Forms,為什麼要找替代?
data-netlify="true" 只在網站由 Netlify 建構和伺服時有效。哪天遷到 GitHub Pages、Vercel 或自己的伺服器,收下來的提交和垃圾過濾就一起留在原地。用一個與平台無關的 action 位址,網站搬到哪裡,收件匣就跟到哪裡。
表單必須搭配 JavaScript 才能用嗎?
不必。端點直接接受原生 HTML 表單 POST,瀏覽器停用腳本也能提交。想讓使用者留在頁內、就地顯示成功提示,再換幾行 fetch 打到同一個端點——位址不變,權杖不變。
怎麼擋住機器人洗表單?
每個端點都有頻率限制,洪水式的洗提交會被擋下;再用一個 CSS 藏起來的蜜罐欄位識破漏網的機器人——真人不會填它,帶蜜罐值的提交在收件匣和查詢結果裡一眼就能認出來,讀取時隨手過濾。
