Kanorio

商業系統

表單

將 Kanorio 表單放置在您自己的前端,並為您處理機器人防護、檔案上傳、同意與聯絡人收集。

請在後台的 行銷 › 線上表單 建立表單,然後將其顯示在您的前端。Kanorio 會檢查機器人與垃圾訊息、儲存提交內容、建立或更新聯絡人、發送確認與團隊郵件,並觸發 customers.form.submitted Webhook。

開始之前,請從後台複製表單 ID。如果瀏覽器從您自己的網域呼叫 API,請將該網域新增至 網站設定 › 開發者 下的 允許的來源。localhost 始終是被允許的。

選項 1:表單元素

<KanorioForm> 可渲染所有問題類型、檔案上傳與同意核取方塊,並為您執行機器人防護。這是最快的方法,且無需升級即可獲得新的防護規則。

import { KanorioProvider, KanorioForm } from "@kanorio/elements";
import "@kanorio/elements/elements.css";

export function ContactSection() {
  return (
    <KanorioProvider siteUrl="https://s-xxxxxxxxxxxx.kanorio.com">
      <KanorioForm formId="cform12345678901234567890" siteName="Sourdough Studio" />
    </KanorioProvider>
  );
}

若未使用 React,請使用 <kanorio-form site-url="…" form-id="…">。請參閱 Elements。

選項 2:您自己的標記

當您想要完全控制 HTML 時,請直接使用 Content Delivery API。

1. 載入表單

GET /api/v1/forms/{id} 會回傳問題、同意設定以及表單是否正在接受回答。如果 availability.accepting 為 false,請顯示關閉訊息而非輸入欄位。

2. 在顯示表單時取得機器人檢查

GET /api/v1/forms/{id}/challenge 會回傳此提交的機器人檢查。其 provider 由網站擁有者在 網站設定 › 機器人防護 中設定:

  • kanorio (預設):altcha 中的內建工作量證明挑戰。SDK 會為您解決(在中階手機上約需半秒),並將結果作為 _tk 發送。
  • turnstile、recaptcha 或 hcaptcha:擁有者自己的金鑰。請使用 siteKey 和 action(Turnstile 亦需 cData)渲染該提供者的元件,並將其權杖作為 captchaToken 傳遞。伺服器會根據網站設定決定驗證哪個提供者,因此來自任何其他提供者的權杖將被拒絕。

每次提交請取得新的挑戰:挑戰與元件權杖皆為單次使用。

3. 提交

發送以問題 ID 為鍵的答案,並附上防護欄位。蜜罐 (Honeypot) 欄位必須為空。

import { forms } from "@kanorio/sdk/forms";

const SITE_URL = "https://s-xxxxxxxxxxxx.kanorio.com";
const FORM_ID = "cform12345678901234567890";
const client = forms.client({ siteUrl: SITE_URL });

// when the form is shown
const renderedAt = Date.now();
const challenge = await client.challenge(FORM_ID);

// when the visitor submits
// built-in: the SDK solves the challenge; third-party: pass the widget token
const protection = await forms.protectionFromChallenge(FORM_ID, challenge, renderedAt, {
  captchaToken: challenge.provider === "kanorio" ? undefined : widgetToken,
});

const result = await client.submit(FORM_ID, {
  answers: { name: "Ada", email: "ada@example.com", message: "Do you ship?" },
  consent: "checked",
  pagePath: window.location.pathname,
  protection,
});

if (!result.ok) {
  // result.error.code, and result.error.issues for INVALID_ANSWERS
}

若未使用 SDK,請使用此內容 POST /api/v1/forms/{id}/submit(顯示內建檢查;若使用第三方提供者,請發送 captchaToken 取代 _tk):

{
  "answers": { "name": "Ada", "email": "ada@example.com" },
  "consent": "checked",
  "pagePath": "/contact",
  "_hp": "",
  "_ts": 1793520000000,
  "_tk": "<solved ALTCHA payload>",
  "_ctx": "cform12345678901234567890"
}

成功的提交會回傳 200 與 {}。如果表單在此期間關閉,內容則為 { "state": "closed" }、"not_open" 或 "full"。

錯誤代碼處理方式
INVALID_ANSWERS顯示 details.issues 中的訊息,並以問題 ID 作為鍵值
VERIFICATION_EXPIRED取得新的驗證挑戰(並重設小工具)後重新提交
DUPLICATE_SUBMISSION告知訪客表單已送出
RATE_LIMITED等待 Retry-After 指定的時間後再重試

檔案上傳

對於檔案問題,請先使用 POST /api/v1/forms/{id}/upload-request 請求上傳票證,並附上問題 ID、檔案名稱、類型與大小,以及來自 forms.uploadProtectionFromChallenge(FORM_ID, challenge, renderedAt, solved) 的防護欄位:使用內建檢查時,這與您提交時使用的已解決挑戰相同;使用第三方提供者時,它會使用挑戰的 uploadToken,因為元件權杖為單次使用且會在提交時檢查。使用回傳的 headers 將檔案 PUT 至 uploadUrl,然後將 uploadId 作為該問題的答案發送。超過問題限制的檔案會失敗並回傳 413 FILE_TOO_LARGE。

提交後

  • 提交內容會出現在後台以及 Management API 的 submissions 下。
  • 聯絡人會根據電子郵件或電話答案進行建立或更新。
  • 確認與團隊郵件會按照表單設定發送。
  • Webhook 訂閱者會收到 customers.form.submitted。

從您的伺服器轉發

您可以從自己的伺服器提交,例如 Next.js 伺服器動作。速率限制適用於每位訪客,因此直接從瀏覽器提交最能保護您的配額。如果您進行轉發,請保持瀏覽器的防護欄位不變。