Skip to content

操作 API 参考

Added in: astro@4.15.0

操作可帮助你构建可从客户端代码和 HTML 表单调用的类型安全后端。定义和调用操作的所有实用程序都由 astro:actions 模块公开。有关示例和使用说明,请参阅 请参阅“操作”指南

¥Actions help you build a type-safe backend you can call from client code and HTML forms. All utilities to define and call actions are exposed by the astro:actions module. For examples and usage instructions, see the Actions guide.

¥Imports from astro:actions

import {
actions,
defineAction,
isInputError,
isActionError,
ActionError,
} from 'astro:actions';

Added in: astro@4.15.0

defineAction() 实用程序用于从 src/actions/index.ts 文件定义新操作。这接受包含要运行的服务器逻辑的 handler() 函数,以及可选的 input 属性以在运行时验证输入参数。

¥The defineAction() utility is used to define new actions from the src/actions/index.ts file. This accepts a handler() function containing the server logic to run, and an optional input property to validate input parameters at runtime.

src/actions/index.ts
import { defineAction } from 'astro:actions';
import { z } from 'astro:schema';
export const server = {
getGreeting: defineAction({
input: z.object({
name: z.string(),
}),
handler: async (input, context) => {
return `Hello, ${input.name}!`
}
})
}

¥handler() property

类型:(input, context) => any

¥Type: (input, context) => any

defineAction() 需要一个 handler() 函数,其中包含在调用操作时运行的服务器逻辑。从处理程序返回的数据会自动序列化并发送给调用者。

¥defineAction() requires a handler() function containing the server logic to run when the action is called. Data returned from the handler is automatically serialized and sent to the caller.

handler() 以用户输入作为其第一个参数进行调用。如果设置了 input 验证器,则在将用户输入传递给处理程序之前,将对其进行验证。第二个参数是一个 context 对象,包含 Astro 的大部分 标准端点上下文,但不包括 getActionResult()callAction()redirect()

¥The handler() is called with user input as its first argument. If an input validator is set, the user input will be validated before being passed to the handler. The second argument is a context object containing most of Astro’s standard endpoint context, excluding getActionResult(), callAction(), and redirect().

使用 贬值库 解析返回值。这支持 JSON 值和 Date()Map()Set()URL() 的实例。

¥Return values are parsed using the devalue library. This supports JSON values and instances of Date(), Map(), Set(), and URL().

¥input validator

类型:ZodType | undefined

¥Type: ZodType | undefined

可选的 input 属性接受 Zod 验证器(例如 Zod 对象、Zod 区分联合)以在运行时验证处理程序输入。如果操作验证失败,则返回 BAD_REQUEST 错误,并且不会调用 handler

¥The optional input property accepts a Zod validator (e.g. Zod object, Zod discriminated union) to validate handler inputs at runtime. If the action fails to validate, a BAD_REQUEST error is returned and the handler is not called.

如果省略 inputhandler 将接收 JSON 请求的 unknown 类型输入和表单请求的 FormData 类型输入。

¥If input is omitted, the handler will receive an input of type unknown for JSON requests and type FormData for form requests.

¥Use with accept: 'form'

如果你的操作接受表单输入,请使用 z.object() 验证器自动将表单数据解析为类型化对象。表单数据字段支持以下验证器:

¥If your action accepts form inputs, use the z.object() validator to automatically parse form data to a typed object. The following validators are supported for form data fields:

  • 可以使用 z.number() 验证类型为 number 的输入

  • 可以使用 z.boolean() 验证类型为 checkbox 的输入

  • 可以使用 z.instanceof(File) 验证类型为 file 的输入

  • 可以使用 z.array(/* validator */) 验证相同 name 的多个输入

  • 所有其他输入都可以使用 z.string() 进行验证

z.object() 验证器还支持扩展函数,包括 .refine().transform().pipe()

¥Extension functions including .refine(), .transform(), and .pipe() are also supported on the z.object() validator.

要应用不同验证器的联合,请使用 z.discriminatedUnion() 封装器根据特定表单字段缩小类型。此示例接受向 “create” 或 “update” 用户提交的表单,使用名为 type 的表单字段来确定要针对哪个对象进行验证:

¥To apply a union of different validators, use the z.discriminatedUnion() wrapper to narrow the type based on a specific form field. This example accepts a form submission to either “create” or “update” a user, using the form field with the name type to determine which object to validate against:

import { defineAction } from 'astro:actions';
import { z } from 'astro:schema';
export const server = {
changeUser: defineAction({
accept: 'form',
input: z.discriminatedUnion('type', [
z.object({
// Matches when the `type` field has the value `create`
type: z.literal('create'),
name: z.string(),
email: z.string().email(),
}),
z.object({
// Matches when the `type` field has the value `update`
type: z.literal('update'),
id: z.number(),
name: z.string(),
email: z.string().email(),
}),
]),
async handler(input) {
if (input.type === 'create') {
// input is { type: 'create', name: string, email: string }
} else {
// input is { type: 'update', id: number, name: string, email: string }
}
},
}),
};

类型:(error?: unknown | ActionError) => boolean

¥Type: (error?: unknown | ActionError) => boolean

Added in: astro@4.15.0

isInputError() 实用程序用于检查 ActionError 是否为输入验证错误。当 input 验证器是 z.object() 时,输入错误包含一个 fields 对象,其中的错误消息按名称分组。

¥The isInputError() utility is used to check whether an ActionError is an input validation error. When the input validator is a z.object(), input errors include a fields object with error messages grouped by name.

See the form input errors guide for more on using isInputError().

类型:(error?: unknown | ActionError) => boolean

¥Type: (error?: unknown | ActionError) => boolean

Added in: astro@4.15.0

isActionError() 实用程序用于检查你的操作是否在 处理程序属性 中引发了 ActionError。当缩小 try / catch 块中一般错误的类型时,这很有用。

¥The isActionError() utility is used to check whether your action raised an ActionError within the handler property. This is useful when narrowing the type of a generic error in a try / catch block.

Added in: astro@4.15.0

ActionError() 构造函数用于创建由操作 handler 抛出的错误。这接受一个描述所发生错误的 code 属性(例如:"UNAUTHORIZED"),以及一个包含更多详细信息的可选 message 属性。

¥The ActionError() constructor is used to create errors thrown by an action handler. This accepts a code property describing the error that occurred (example: "UNAUTHORIZED"), and an optional message property with further details.

Added in: astro@4.15.0

code 属性接受所有 HTTP 状态代码的人类可读版本。支持以下代码:

¥The code property accepts human-readable versions of all HTTP status codes. The following codes are supported:

  • BAD_REQUEST (400):客户端发送了无效输入。当操作 input 验证器验证失败时,会抛出此错误。

  • UNAUTHORIZED (401):客户端缺少有效的身份验证凭据。

  • FORBIDDEN (403):客户端无权访问资源。

  • NOT_FOUND (404):服务器找不到请求的资源。

  • METHOD_NOT_SUPPORTED (405):服务器不支持请求的方法。

  • TIMEOUT (408):服务器在处理请求时超时。

  • CONFLICT (409):由于冲突,服务器无法更新资源。

  • PRECONDITION_FAILED (412):服务器不满足请求的先决条件。

  • PAYLOAD_TOO_LARGE (413):服务器无法处理请求,因为有效负载太大。

  • UNSUPPORTED_MEDIA_TYPE (415):服务器不支持请求的媒体类型。注意:操作已经检查了 Content-Type 标头 的 JSON 和表单请求,因此你可能不需要手动引发此代码。

  • UNPROCESSABLE_CONTENT (422):由于语义错误,服务器无法处理请求。

  • TOO_MANY_REQUESTS (429):服务器已超过指定的速率限制。

  • CLIENT_CLOSED_REQUEST (499):客户端在服务器响应之前关闭了请求。

  • INTERNAL_SERVER_ERROR (500):服务器意外失败。

  • NOT_IMPLEMENTED (501):服务器不支持请求的功能。

  • BAD_GATEWAY (502):服务器从上游服务器收到无效响应。

  • SERVICE_UNAVAILABLE (503):服务器暂时不可用。

  • GATEWAY_TIMEOUT (504):服务器从上游服务器收到超时。

Added in: astro@4.15.0

message 属性接受一个字符串。(例如 “用户必须登录。”)

¥The message property accepts a string. (e.g. “User must be logged in.“)

类型:(context: APIContext) => ActionMiddlewareContext

¥Type: (context: APIContext) => ActionMiddlewareContext

Added in: astro@5.0.0

getActionContext() 是从中间件处理程序调用的函数,用于检索有关入站操作请求的信息。

¥getActionContext() is a function called from your middleware handler to retrieve information about inbound action requests.

此函数返回一个 action 对象,其中包含有关请求的信息,以及 setActionResult()serializeActionResult() 函数以编程方式设置 Astro.getActionResult() 返回的值。

¥This function returns an action object with information about the request, and the setActionResult() and serializeActionResult() functions to programmatically set the value returned by Astro.getActionResult().

getActionContext() 允许你以编程方式使用中间件获取和设置操作结果,允许你持久保存 HTML 表单的操作结果、通过添加的安全检查来控制操作请求等等。

¥getActionContext() lets you programmatically get and set action results using middleware, allowing you to persist action results from HTML forms, gate action requests with added security checks, and more.

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
const { action, setActionResult, serializeActionResult } = getActionContext(context);
if (action?.calledFrom === 'form') {
const result = await action.handler();
setActionResult(action.name, serializeActionResult(result));
}
return next();
});

类型:{ calledFrom: 'rpc' | 'form', name: string, handler: () => Promise<SafeResult<any, any>> } | undefined

¥Type: { calledFrom: 'rpc' | 'form', name: string, handler: () => Promise<SafeResult<any, any>> } | undefined

action 是一个包含有关入站操作请求的信息的对象。

¥action is an object containing information about an inbound action request.

它可从 getActionContext() 获得,并提供操作名称、处理程序以及操作是从客户端 RPC 函数(例如 actions.newsletter())还是 HTML 表单操作调用的。

¥It is available from getActionContext(), and provides the action name, handler, and whether the action was called from an client-side RPC function (e.g. actions.newsletter()) or an HTML form action.

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
const { action, setActionResult, serializeActionResult } = getActionContext(context);
if (action?.calledFrom === 'rpc' && action.name.startsWith('private')) {
// Check for a valid session token
}
// ...
});

类型:(actionName: string, actionResult: SerializedActionResult) => void

¥Type: (actionName: string, actionResult: SerializedActionResult) => void

setActionResult() 是一个函数,用于在中间件中以编程方式设置 Astro.getActionResult() 返回的值。它传递了由 serializeActionResult() 序列化的操作名称和操作结果。

¥setActionResult() is a function to programmatically set the value returned by Astro.getActionResult() in middleware. It is passed the action name and an action result serialized by serializeActionResult().

当从 HTML 表单调用操作以持久保存和加载会话结果时,这很有用。

¥This is useful when calling actions from an HTML form to persist and load results from a session.

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
const { action, setActionResult, serializeActionResult } = getActionContext(context);
if (action?.calledFrom === 'form') {
const result = await action.handler();
// ... handle the action result
setActionResult(action.name, serializeActionResult(result));
}
return next();
});
See the advanced sessions guide for a sample implementation using Netlify Blob.

类型:(result: SafeResult<any, any>) => SerializedActionResult

¥Type: (result: SafeResult<any, any>) => SerializedActionResult

serializeActionResult() 将操作结果序列化为 JSON 以进行持久化。这是正确处理非 JSON 返回值(如 MapDate)以及 ActionError 对象所必需的。

¥serializeActionResult() will serialize an action result to JSON for persistence. This is required to properly handle non-JSON return values like Map or Date as well as the ActionError object.

在序列化要传递给 setActionResult() 的操作结果时调用此函数:

¥Call this function when serializing an action result to be passed to setActionResult():

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
const { action, setActionResult, serializeActionResult } = getActionContext(context);
if (action) {
const result = await action.handler();
setActionResult(action.name, serializeActionResult(result));
}
// ...
});

类型:(result: SerializedActionResult) => SafeResult<any, any>

¥Type: (result: SerializedActionResult) => SafeResult<any, any>

deserializeActionResult() 将反转 serializeActionResult() 的效果并将操作结果返回到其原始状态。这对于访问序列化操作结果上的 dataerror 对象很有用。

¥deserializeActionResult() will reverse the effect of serializeActionResult() and return an action result to its original state. This is useful to access the data and error objects on a serialized action result.

类型:(action: ActionClient<any, any, any>) => string

¥Type: (action: ActionClient<any, any, any>) => string

Added in: astro@5.1.0

getActionPath() 实用程序接受操作并返回 URL 路径,以便你可以直接将操作调用作为 fetch() 操作执行。这允许你在调用操作时提供详细信息,例如自定义标头。然后,你可以根据需要 处理自定义格式的返回数据,就像你直接调用操作一样。

¥The getActionPath() utility accepts an action and returns a URL path so you can execute an action call as a fetch() operation directly. This allows you to provide details such as custom headers when you call your action. Then, you can handle the custom-formatted returned data as needed, just as if you had called an action directly.

此示例显示如何调用传递 Authorization 标头和 keepalive 选项的已定义 like 操作:

¥This example shows how to call a defined like action passing the Authorization header and the keepalive option:

src/components/my-component.astro
<script>
import { actions, getActionPath } from 'astro:actions'
await fetch(getActionPath(actions.like), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer YOUR_TOKEN'
},
body: JSON.stringify({ id: 'YOUR_ID' }),
keepalive: true
})
</script>

此示例显示如何使用 sendBeacon API 调用相同的 like 操作:

¥This example shows how to call the same like action using the sendBeacon API:

src/components/my-component.astro
<script>
import { actions, getActionPath } from 'astro:actions'
navigator.sendBeacon(
getActionPath(actions.like),
new Blob([JSON.stringify({ id: 'YOUR_ID' })], {
type: 'application/json'
})
)
</script>
Astro 中文网 - 粤ICP备13048890号