תיעוד 210
טיפול בשליחת טפסים עם Airtable
במדריך זה תשתמשו ב-Cloudflare Workers וב-Airtable כדי לשמור שליחות טופס מממשק משתמש בצד הלקוח. Airtable הוא פתרון גיליון אלקטרוני חינמי לשימוש, עם API נגיש למפתחים. Workers יטפלו בשליחות טופס נכנסות וישתמשו ב-REST API של Airtable כדי לשמור את הנתונים באופן אסינכרוני ב-base של Airtable (המונח של Airtable לגיליון אלקטרוני) לעיון מאוחר יותר.

#לפני שמתחילים
כל המדריכים מניחים שכבר השלמתם את מדריך תחילת העבודה, שמגדיר לכם חשבון Cloudflare Workers, C3 ו-Wrangler.
#1. יצירת טופס
במדריך זה תבנו פונקציית Workers שמטפלת בקלט מטופס יצירת קשר. הטופס שהמדריך מתייחס אליו יאסוף שם פרטי, שם משפחה, כתובת דוא"ל, מספר טלפון, נושא הודעה והודעה.
בניית טופס
אם זו הפעם הראשונה שאתם בונים טופס ואתם רוצים לעקוב אחרי מדריך ליצירת טופס עם Cloudflare Pages, עיינו במדריך HTML forms.
עיינו בדוגמה מפושטת של הטופס שבשימוש במדריך זה. שימו לב שהפרמטר action של תגית <form> צריך להצביע על אפליקציית Workers הפרוסה שתבנו במדריך זה.
קוד צד הלקוח שלכם, html
<form action="https://workers-airtable-form.signalnerve.workers.dev/submit" method="POST">
<div>
<label for="first_name">First name</label>
<input type="text" name="first_name" id="first_name" autocomplete="given-name" placeholder="Ellen" required />
</div>
<div>
<label for="last_name">Last name</label>
<input type="text" name="last_name" id="last_name" autocomplete="family-name" placeholder="Ripley" required />
</div>
<div>
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" placeholder="[email protected]" required />
</div>
</div>
<div>
<label for="phone">
Phone
<span>Optional</span>
</label>
<input type="text" name="phone" id="phone" autocomplete="tel" placeholder="+1 (123) 456-7890" />
</div>
<div>
<label for="subject">Subject</label>
<input type="text" name="subject" id="subject" placeholder="Your example subject" required />
</div>
<div>
<label for="message">
Message
<span>Max 500 characters</span>
</label>
<textarea id="message" name="message" rows="4" placeholder="Tenetur quaerat expedita vero et illo. Tenetur explicabo dolor voluptatem eveniet. Commodi est beatae id voluptatum porro laudantium. Quam placeat accusamus vel officiis vel. Et perferendis dicta ut perspiciatis quos iste. Tempore autem molestias voluptates in sapiente enim doloremque." required></textarea>
</div>
<div>
<button type="submit">
Submit
</button>
</div>
</form>#2. יצירת פרויקט Worker
כדי לטפל בשליחת הטופס, צרו ופרסו Worker שמפענח את נתוני הטופס הנכנסים ומכין אותם לשליחה ל-Airtable.
צרו פרויקט Worker חדש בשם airtable-form-handler:
npm
npm create cloudflare@latest -- airtable-form-handleryarn
yarn create cloudflare airtable-form-handlerpnpm
pnpm create cloudflare@latest airtable-form-handlerלהגדרה, בחרו את האפשרויות הבאות:
- עבור What would you like to start with?, בחרו
Hello World example. - עבור Which template would you like to use?, בחרו
Worker only. - עבור Which language do you want to use?, בחרו
JavaScript. - עבור Do you want to use git for version control?, בחרו
Yes. - עבור Do you want to add an AGENTS.md file to help AI coding tools understand Cloudflare APIs?, בחרו
Yes. - עבור Do you want to deploy your application?, בחרו
No(נבצע כמה שינויים לפני הפריסה).
לאחר מכן, עברו לתיקייה שנוצרה:
cd airtable-form-handler#3. הגדרת base של Airtable
כשה-Worker יושלם, הוא ישלח נתונים ל-base של Airtable דרך REST API של Airtable.
אם אין לכם חשבון Airtable, צרו אחד (התוכנית החינמית מספיקה להשלמת המדריך הזה). בלוח הבקרה של Airtable, צרו base חדש על ידי בחירה ב-Start from scratch.
אחרי שיצרתם base חדש, הגדירו אותו לשימוש עם הטופס בצד הלקוח. מחקו את העמודות הקיימות, וצרו שש עמודות, עם סוגי השדות הבאים:
| Field name | Airtable field type |
|---|---|
| First Name | "Single line text" |
| Last Name | "Single line text" |
| "Email" | |
| Phone Number | "Phone number" |
| Subject | "Single line text" |
| Message | "Long text" |
שימו לב ששמות השדות רגישים לאותיות גדולות וקטנות. אם תשנו את שמות השדות, תצטרכו להתאים במדויק את שמות השדות החדשים בבקשת ה-API שתשלחו ל-Airtable בהמשך המדריך. לבסוף, אפשר לשנות את שם הטבלה. כברירת מחדל יהיה לה שם כמו Table 1. בקוד שלמטה מניחים שהטבלה שונתה לשם תיאורי יותר, כמו Form Submissions.
לאחר מכן, עברו אל דף ה-API של Airtable ובחרו את ה-base החדש. שימו לב שצריך להיות מחוברים ל-Airtable כדי לראות את פרטי ה-base. בדף תיעוד ה-API, מצאו את Airtable base ID.
תצטרכו גם ליצור Personal access token שישמש לגישה ל-base של Airtable. אפשר לעשות זאת בדף Personal access tokens באתר של Airtable וליצור token חדש. ודאו שה-token מוגדר כך:
- Scope: ה-scope
data.records:writeחייב להיות מוגדר על ה-token - Access: יש להעניק גישה ל-base שעבדתם איתו במדריך זה
את ה-access token שנוצר יש להגדיר עכשיו באפליקציה. כדי להפוך את ה-token לזמין בבסיס הקוד, השתמשו בפקודה wrangler secret. הפקודה secret מצפינה ושומרת משתני סביבה לשימוש בפונקציה, בלי לחשוף אותם למשתמשים.
הריצו wrangler secret put, והעבירו את AIRTABLE_ACCESS_TOKEN כשם הסוד:
npx wrangler secret put AIRTABLE_ACCESS_TOKENEnter the secret text you would like assigned to the variable AIRTABLE_ACCESS_TOKEN on the script named airtable-form-handler:
******
🌀 Creating the secret for script name airtable-form-handler
✨ Success! Uploaded secret AIRTABLE_ACCESS_TOKEN.לפני שממשיכים, עיינו במפתחות שאמורים להיות לכם מ-Airtable:
- Airtable Table Name: השם של הטבלה, כמו Form Submissions.
- Airtable Base ID: מזהה ה-base האלפאנומרי שנמצא בראש דף ה-API של ה-base.
- Airtable Access Token: Personal Access Token שהמשתמש יצר כדי לגשת למידע על ה-base החדש של Airtable.
#4. שליחת נתונים ל-Airtable
כשה-base של Airtable מוגדר, והמפתחות והמזהים שנדרשים לתקשורת עם ה-API מוכנים, תגדירו עכשיו את ה-Worker כדי לשמור נתונים מהטופס ב-Airtable.
בקובץ index.js של פרויקט ה-Worker, החליפו את קוד ברירת המחדל ב-fetch handler של Workers שיכול להגיב לבקשות. כשלכתובת המבוקשת יש pathname של /submit, תטפלו בשליחת טופס חדשה. אחרת, תחזירו תגובת 404 Not Found.
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/submit") {
return submitHandler(request, env);
}
return new Response("Not found", { status: 404 });
},
};ל-submitHandler יש שתי פונקציות. ראשית, הוא יפענח את נתוני הטופס שמגיעים מטופס HTML5. אחרי שהנתונים מפוענחים, השתמשו ב-API של Airtable כדי לשמור שורה חדשה (שליחת טופס חדשה) בטבלה:
async function submitHandler(request, env) {
if (request.method !== "POST") {
return new Response("Method Not Allowed", {
status: 405,
headers: { Allow: "POST" },
});
}
const body = await request.formData();
const { first_name, last_name, email, phone, subject, message } =
Object.fromEntries(body);
// The keys in "fields" are case-sensitive, and
// should exactly match the field names you set up
// in your Airtable table, such as "First Name".
const reqBody = {
fields: {
"First Name": first_name,
"Last Name": last_name,
Email: email,
"Phone Number": phone,
Subject: subject,
Message: message,
},
};
await createAirtableRecord(env, reqBody);
return new Response("Thanks for your submission", { status: 200 });
}
// Existing code
// export default ...מניעת שגיאות אפשריות בגישה ל-request.body
את הגוף של Request אפשר לגשת אליו רק פעם אחת. אם כבר השתמשתם ב-request.formData() באותה בקשה, ייתכן שתיתקלו ב-TypeError כשתנסו לגשת ל-request.body.
כדי להימנע משגיאות, צרו עותק של אובייקט ה-Request עם request.clone() לכל ניסיון נוסף לגשת לגוף של Request. קחו בחשבון של-Workers יש מגבלת זיכרון של 128 MB לכל Worker, וטעינה של קבצים גדולים במיוחד לזיכרון של Worker כמה פעמים עלולה להגיע למגבלה הזו. כדי לוודא ששימוש בזיכרון לא מגיע למגבלה, שקלו להשתמש ב-Streams.
רוב הפונקציה הזו עוסקת בפענוח גוף הבקשה (הנתונים שנשלחים כחלק מהבקשה), אבל יש שני דברים חשובים לשים לב אליהם. ראשית, אם מתודת ה-HTTP שנשלחה לפונקציה הזו אינה POST, תחזירו תגובה חדשה עם קוד הסטטוס 405 Method Not Allowed וכותרת Allow: POST שמפרטת את המתודה שהנתיב הזה מקבל.
המשתנה reqBody מייצג אוסף של שדות, שהם זוגות מפתח-ערך לכל עמודה בטבלת Airtable. על ידי עיצוב reqBody כאובייקט עם אוסף שדות, אתם יוצרים רשומה חדשה בטבלה עם ערך לכל שדה.
לאחר מכן אתם קוראים ל-createAirtableRecord (הפונקציה שתגדירו בהמשך). הפונקציה createAirtableRecord מקבלת פרמטר body, שתואם לפורמט הנדרש של ה-API של Airtable, כלומר אובייקט JavaScript שמכיל זוגות מפתח-ערך תחת fields, ומייצג רשומה אחת ליצירה בטבלה:
async function createAirtableRecord(env, body) {
try {
const result = fetch(
`https://api.airtable.com/v0/${env.AIRTABLE_BASE_ID}/${encodeURIComponent(env.AIRTABLE_TABLE_NAME)}`,
{
method: "POST",
body: JSON.stringify(body),
headers: {
Authorization: `Bearer ${env.AIRTABLE_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
},
);
return result;
} catch (error) {
console.error(error);
}
}
// Existing code
// async function submitHandler
// export default ...כדי לבצע בקשה מאומתת ל-Airtable, צריך לספק ארבעה קבועים שמייצגים נתונים על חשבון Airtable, ה-base ושם הטבלה. כבר הגדרתם את AIRTABLE_ACCESS_TOKEN באמצעות wrangler secret, כי זה ערך שצריך להיות מוצפן. Airtable base ID ושם הטבלה, וגם FORM_URL, הם ערכים שאפשר לשתף בפומבי במקומות כמו GitHub. השתמשו בתכונת vars של Wrangler כדי להעביר משתני סביבה ציבוריים מקובץ Wrangler.
הוסיפו טבלת vars בסוף קובץ Wrangler:
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "workers-airtable-form",
"main": "src/index.js",
"upload_source_maps": true,
// Set this to today's date
"compatibility_date": "2026-10-23",
"vars": {
"AIRTABLE_BASE_ID": "exampleBaseId",
"AIRTABLE_TABLE_NAME": "Form Submissions"
}
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "workers-airtable-form"
main = "src/index.js"
upload_source_maps = true
# Set this to today's date
compatibility_date = "2026-10-23"
[vars]
AIRTABLE_BASE_ID = "exampleBaseId"
AIRTABLE_TABLE_NAME = "Form Submissions"אחרי שכל השדות האלה נשלחו, הגיע הזמן לפרוס את פונקציית Workers ללא שרת ולחבר את הטופס אליה. ראשית, פרסמו את ה-Worker:
פריסת ה-Worker, sh
npx wrangler deployפרויקט ה-Worker ייפרס לכתובת ייחודית, לדוגמה https://workers-airtable-form.cloudflare.workers.dev. זה החלק הראשון של מאפיין action בטופס בצד הלקוח. החלק השני הוא הנתיב של מטפל הטופס, שהוא /submit. בממשק בצד הלקוח, הגדירו את תגית form כפי שמוצג למטה:
<form
action="https://workers-airtable-form.cloudflare.workers.dev/submit"
method="POST"
class="..."
>
<!-- The rest of your HTML form -->
</form>אחרי שפרסתם את הטופס החדש (עיינו במדריך HTML forms אם אתם צריכים עזרה ביצירת טופס), אתם אמורים להיות מסוגלים לשלוח שליחת טופס חדשה ולראות את הערך מופיע מיד ב-Airtable:

#סיכום
עם השלמת המדריך הזה, יצרתם Worker שיכול לקבל שליחות טופס ולשמור אותן ב-Airtable. למדתם איך לפענח נתוני טופס, להגדיר משתני סביבה, ולהשתמש ב-API של fetch כדי לבצע בקשות לשירותים חיצוניים מחוץ ל-Worker.