Web 表单

在 Next.js 和 Drupal 中使用 Web 表单


在 Next.js 中,有两种方法可以处理 Drupal 的 Web 表单

  1. 客户端
  2. 服务器端 (API 路由)

两种实现都使用 Webform REST 模块。


演示

请查看 https://example-webform.next-drupal.org


安装

  1. 安装 Webform REST 模块: composer require drupal/webform_rest
  2. 访问 /admin/config/services/rest 并启用 **Webform Submit** 资源。您可能需要为此路由存在而启用 Rest UI 模块。
  3. 为 **方法** 选择 POST,为 **接受的请求格式** 选择 json,为 **身份验证提供程序** 选择 cookie
  4. 保存配置
  5. 接下来,访问 /admin/people/permissions 并授予匿名用户 **在 Webform Submit 资源上访问 POST** 权限。

客户端

我们使用 Webform REST 模块将表单值直接提交到 Drupal。

注意:在客户端提交 Webform 值时,webform_id 和 Drupal 基本 URL 会被公开。

export default function ContactPage() {
async function handleSubmit(event) {
event.preventDefault()
const response = await fetch(
`${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}/webform_rest/submit`,
{
method: "POST",
body: JSON.stringify({
webform_id: "contact",
name: event.target.name.value,
email: event.target.email.value,
}),
headers: {
"Content-Type": "application/json",
},
}
)
if (response.ok) {
// Show success.
}
// Handle error.
}
return (
<div>
<form onSubmit={handleSubmit}>
<p>Implement your form here</p>
<div>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" />
</div>
<div>
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" />
</div>
<button type="submit">Submit</button>
</form>
</div>
)
}

服务器端

我们将表单值首先提交到自定义 API 路由。然后,API 路由使用 Webform REST 模块将表单提交到 Drupal。

如果我们需要隐藏客户端 ID 和密钥或我们的 Drupal 实现,这将非常有用。

  1. 创建一个 /pages/api/contact API 路由来处理我们的 POST 请求。

pages/api/contact.ts

import { NextApiRequest, NextApiResponse } from "next"
import { drupal } from "lib/drupal"
export default async function handler(
request: NextApiRequest,
response: NextApiResponse
) {
try {
if (request.method === "POST") {
const url = drupal.buildUrl("/webform_rest/submit")
// Submit to Drupal.
const result = await drupal.fetch(url.toString(), {
method: "POST",
body: JSON.stringify({
webform_id: "contact",
name: request.body.name,
email: request.body.email,
}),
headers: {
"Content-Type": "application/json",
},
})
if (!result.ok) {
throw new Error()
}
response.status(200).end()
}
} catch (error) {
return response.status(400).json(error.message)
}
}
  1. 接下来,更新我们的联系表单以提交到此 API 路由。
export default function ContactPage() {
async function handleSubmit(event) {
event.preventDefault()
const response = await fetch(`/api/contact`, {
method: "POST",
body: JSON.stringify({
name: event.target.name.value,
email: event.target.email.value,
}),
})
if (response.ok) {
// Show success.
}
// Handle error.
}
return (
<div>
<form onSubmit={handleSubmit}>
<p>Implement your form here</p>
<div>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" />
</div>
<div>
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" />
</div>
<button type="submit">Submit</button>
</form>
</div>
)
}

示例

请查看 example-webform,了解使用 **react-hook-form** 构建 Webform 并使用 **yup** 处理验证的实际示例。