在本指南中,你将学习如何将用于接收表单提交的 Worker 重构为可托管在 Cloudflare Pages 应用上的 Pages Function。Pages Functions 是与应用位于同一项目目录内的无服务器函数,随 Cloudflare Pages 一起部署。它使你能够运行添加动态功能的服务端代码,而无需运行专用服务器。你可能因以下原因之一将 Worker 重构为 Pages Function:
- 若你管理 Pages 应用依赖的无服务器函数,并希望交付逻辑而无需将 Worker 作为独立服务管理。
- 若你正在将 Worker 迁移到 Pages Functions,并希望使用 Pages Functions 的路由和中间件能力。
- 移除 fetch 处理程序,替换为适当的
OnRequest方法。请参阅 Functions 为你的 Function 选择适当的方法。 - 将
context对象作为参数传递给新的OnRequest方法,以访问 context 参数的属性:request、env、params和next。 - 使用中间件处理必须在路由处理程序之前或之后执行的逻辑。在 Functions 文档中了解更多 使用中间件 的信息。
为说明重构过程,本指南使用简单的表单提交示例。
表单提交可由 Workers 处理,但由于表单通常特定于某个应用,也可能是 Pages Functions 的良好用例。
假设你已使用 Worker 处理表单,则已部署该 Worker 并在 HTML 表单的 action 属性中添加 URL。这意味着当你更改 Worker 处理提交的方式时,必须修改 Worker 脚本。若 Worker 中的逻辑被多个应用使用,Pages Functions 则不是合适的用例。
但在希望将函数逻辑与应用组织在同一项目目录中时,使用 Pages Function 可能更有益。
使用 Pages Functions 构建应用可帮助你从同一位置管理客户端和无服务器逻辑,并更轻松地编写和调试代码。
Airtable ↗ 是一个用于构建协作应用的低代码平台。它帮助自定义工作流、协作和处理表单提交。在本示例中,你将利用 Airtable 的表单提交功能。
Airtable ↗ 可用于在同一账户的不同表中存储信息条目。创建用于处理提交逻辑的 Worker 时,第一步是使用 Wrangler 在特定文件夹或应用根目录初始化新 Worker。
此步骤创建编写 Airtable 提交 Worker 的样板。编写 Worker 后,在 配置项目以进行部署 后,可将其部署到 Cloudflare 全球网络。有关如何使用 Workers 处理 Airtable 表单提交 的完整教程,请参阅 Workers 文档。
以下代码块展示了处理 Airtable 表单提交的 Worker 示例。
若 Worker 的路径名为 /submit,则调用 submitHandler 异步函数。此函数检查请求方法是否为 POST,然后解析表单条目并使用凭据(可通过 Wrangler secret 存储)发布到 Airtable。
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === "/submit") {
return submitHandler(request, env);
}
return fetch(request.url);
},
};
async function submitHandler(request, env) {
if (request.method !== "POST") {
return new Response("Method not allowed", {
status: 405,
});
}
const body = await request.formData();
const { first_name, last_name, email, phone, subject, message } =
Object.fromEntries(body);
const reqBody = {
fields: {
"First Name": first_name,
"Last Name": last_name,
Email: email,
"Phone number": phone,
Subject: subject,
Message: message,
},
};
return HandleAirtableData(reqBody, env);
}
const HandleAirtableData = (body, env) => {
return 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_API_KEY}`,
"Content-type": `application/json`,
},
},
);
};要重构上述 Worker,请前往 Pages 项目目录并创建 /functions 文件夹。在 /functions 中创建 form.js 文件。此文件将处理表单提交。
然后在 form.js 文件中,导出一个 onRequestPost:
export async function onRequestPost(context) {
return await submitHandler(context);
}每个 Worker 都有 addEventListener 来监听 fetch 事件,但在 Pages Function 中不需要。相反,你将 export 单个 onRequest 函数,并根据其处理的 HTTPS 请求命名。请参阅 Function 文档 为你的 function 选择适当的方法。
上述代码将 request 和 env 作为参数传递,这些属性会传递给 submitHandler 函数,该函数与 原始 Worker 保持不变。但由于 Functions 允许指定 HTTPS 请求类型,你可以移除 Worker 中的 request.method 检查。这现在由 Pages Functions 通过命名 onRequest 处理程序来处理。
现在,你将引入 submitHandler 函数并传递 env 参数作为属性。这允许你在下面的 HandleAirtableData 函数中访问 env。此函数使用 Airtable 凭据向 Airtable 执行 POST 请求:
export async function onRequestPost(context) {
return await submitHandler(context);
}
async function submitHandler(context) {
const body = await context.request.formData();
const { first_name, last_name, email, phone, subject, message } =
Object.fromEntries(body);
const reqBody = {
fields: {
"First Name": first_name,
"Last Name": last_name,
Email: email,
"Phone number": phone,
Subject: subject,
Message: message,
},
};
return HandleAirtableData({ body: reqBody, env: env });
}最后,创建 HandleAirtableData 函数。此函数将 fetch 请求发送到 Airtable,携带 Airtable 凭据和请求体:
// ..
const HandleAirtableData = async function onRequest({ body, env }) {
return 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_API_KEY}`,
"Content-type": `application/json`,
},
},
);
};你可以 使用 Wrangler 在本地测试 Function。完成本指南后,你已成功将表单提交 Worker 重构为表单提交 Pages Function。