Skip to content

端点

Astro 允许你创建自定义端点来提供任何类型的数据。你可以使用它来生成图片、公开 RSS 文档或将它们用作 API 路由来为你的站点构建完整的 API。

¥Astro lets you create custom endpoints to serve any kind of data. You can use this to generate images, expose an RSS document, or use them as API Routes to build a full API for your site.

在静态生成的站点中,你的自定义端点在构建时被调用以生成静态文件。如果你选择使用 SSR 模式,自定义端点将变成根据请求调用的实时服务器端点。静态端点和 SSR 端点的定义类似,但 SSR 端点支持其他功能。

¥In statically-generated sites, your custom endpoints are called at build time to produce static files. If you opt in to SSR mode, custom endpoints turn into live server endpoints that are called on request. Static and SSR endpoints are defined similarly, but SSR endpoints support additional features.

¥Static File Endpoints

要创建自定义端点,请将 .js.ts 文件添加到 /pages 目录。.js.ts 扩展名将在构建过程中被删除,因此文件名应包含你要创建的数据的扩展名。例如,src/pages/data.json.ts 将构建 /data.json 端点。

¥To create a custom endpoint, add a .js or .ts file to the /pages directory. The .js or .ts extension will be removed during the build process, so the name of the file should include the extension of the data you want to create. For example, src/pages/data.json.ts will build a /data.json endpoint.

端点导出一个 GET 函数(可选 async),该函数接收具有类似于 Astro 全局属性的 上下文对象。在这里,它返回一个带有 nameurl 的 Response 对象,Astro 将在构建时调用它并使用主体的内容来生成文件。

¥Endpoints export a GET function (optionally async) that receives a context object with properties similar to the Astro global. Here, it returns a Response object with a name and url, and Astro will call this at build time and use the contents of the body to generate the file.

src/pages/builtwith.json.ts
// Outputs: /builtwith.json
export async function GET({params, request}) {
return new Response(
JSON.stringify({
name: 'Astro',
url: 'https://astro.build/'
})
)
}

从 Astro v3.0 开始,返回的 Response 对象不再需要包含 encoding 属性。例如,要生成二进制 png 图片:

¥Since Astro v3.0, the returned Response object doesn’t have to include the encoding property anymore. For example, to produce a binary png image:

src/pages/astro-logo.png.ts
export async function GET({ params, request }) {
const response = await fetch("https://astro.nodejs.cn/assets/full-logo-light.png");
return new Response(await response.arrayBuffer());
}

你还可以使用 APIRoute 类型键入端点函数:

¥You can also type your endpoint functions using the APIRoute type:

import type { APIRoute } from 'astro';
export const GET: APIRoute = async ({ params, request }) => {...}

¥params and Dynamic routing

端点支持与页面相同的 动态路由 功能。使用括号中的参数名称命名你的文件并导出 getStaticPaths() 功能。然后,你可以使用传递给端点函数的 params 属性来访问参数:

¥Endpoints support the same dynamic routing features that pages do. Name your file with a bracketed parameter name and export a getStaticPaths() function. Then, you can access the parameter using the params property passed to the endpoint function:

src/pages/api/[id].json.ts
import type { APIRoute } from 'astro';
const usernames = ["Sarah", "Chris", "Yan", "Elian"]
export const GET: APIRoute = ({ params, request }) => {
const id = params.id;
return new Response(
JSON.stringify({
name: usernames[id]
})
)
}
export function getStaticPaths() {
return [
{ params: { id: "0"} },
{ params: { id: "1"} },
{ params: { id: "2"} },
{ params: { id: "3"} }
]
}

这将在构建时生成四个 JSON 端点:/api/0.json/api/1.json/api/2.json/api/3.json。使用端点的动态路由的工作方式与使用页面的方式相同,但由于端点是函数而不是组件,因此不支持 props

¥This will generate four JSON endpoints at build time: /api/0.json, /api/1.json, /api/2.json and /api/3.json. Dynamic routing with endpoints works the same as it does with pages, but because the endpoint is a function and not a component, props aren’t supported.

所有端点都会收到 request 属性,但在静态模式下,你只能访问 request.url。这将返回当前端点的完整 URL,其工作方式与 Astro.request.url 对于页面的作用相同。

¥All endpoints receive a request property, but in static mode, you only have access to request.url. This returns the full URL of the current endpoint and works the same as Astro.request.url does for pages.

src/pages/request-path.json.ts
import type { APIRoute } from 'astro';
export const GET: APIRoute = ({ params, request }) => {
return new Response(JSON.stringify({
path: new URL(request.url).pathname
})
)
}

服务器端点(API 路由)

Section titled 服务器端点(API 路由)

¥Server Endpoints (API Routes)

静态文件端点部分中描述的所有内容也可以在 SSR 模式下使用:文件可以导出 GET 函数,该函数接收具有类似于 Astro 全局属性的 上下文对象

¥Everything described in the static file endpoints section can also be used in SSR mode: files can export a GET function which receives a context object with properties similar to the Astro global.

但是,与 static 模式不同,当你为路由启用按需渲染时,端点将在请求时构建。这解锁了构建时不可用的新功能,并允许你构建监听请求并在运行时在服务器上安全执行代码的 API 路由。

¥But, unlike in static mode, when you enable on-demand rendering for a route, the endpoint will be built when it is requested. This unlocks new features that are unavailable at build time, and allows you to build API routes that listen for requests and securely execute code on the server at runtime.

server 模式下,你的路由将默认按需渲染。在 hybrid 模式下,你必须选择退出使用 export const prerender = false 的每个自定义端点的预渲染。

¥Your routes will be rendered on demand by default in server mode. In hybrid mode, you must opt out of prerendering for each custom endpoint with export const prerender = false.

服务器端点可以访问 params 而无需导出 getStaticPaths,并且它们可以返回 Response 对象,允许你设置状态代码和标头:

¥Server endpoints can access params without exporting getStaticPaths, and they can return a Response object, allowing you to set status codes and headers:

src/pages/[id].json.js
import { getProduct } from '../db';
export async function GET({ params }) {
const id = params.id;
const product = await getProduct(id);
if (!product) {
return new Response(null, {
status: 404,
statusText: 'Not found'
});
}
return new Response(
JSON.stringify(product), {
status: 200,
headers: {
"Content-Type": "application/json"
}
}
);
}

这将响应与动态路由匹配的任何请求。例如,如果我们导航到 /helmet.json,则 params.id 将设置为 helmet。如果模拟产品数据库中存在 helmet,端点将使用创建 Response 对象来以 JSON 进行响应并返回成功的 HTTP 状态码。如果没有,它将使用 Response 对象来响应 404

¥This will respond to any request that matches the dynamic route. For example, if we navigate to /helmet.json, params.id will be set to helmet. If helmet exists in the mock product database, the endpoint will use create a Response object to respond with JSON and return a successful HTTP status code. If not, it will use a Response object to respond with a 404.

在 SSR 模式下,某些提供商需要 Content-Type 标头才能返回图片。在本例中,使用 Response 对象来指定 headers 属性。例如,要生成二进制 .png 图片:

¥In SSR mode, certain providers require the Content-Type header to return an image. In this case, use a Response object to specify a headers property. For example, to produce a binary .png image:

src/pages/astro-logo.png.ts
export async function GET({ params, request }) {
const response = await fetch("https://astro.nodejs.cn/assets/full-logo-light.png");
const buffer = Buffer.from(await response.arrayBuffer());
return new Response(buffer, {
headers: { "Content-Type": "image/png" },
});
}

¥HTTP methods

除了 GET 函数外,你还可以导出名称为任意 HTTP 方式 的函数。当有请求进来时,Astro 会检查方法并调用相应的函数。

¥In addition to the GET function, you can export a function with the name of any HTTP method. When a request comes in, Astro will check the method and call the corresponding function.

你还可以导出 ALL 函数以匹配任何没有相应导出函数的方法。如果有一个请求没有匹配的方法,它将重定向到你网站的 404 页面

¥You can also export an ALL function to match any method that doesn’t have a corresponding exported function. If there is a request with no matching method, it will redirect to your site’s 404 page.

src/pages/methods.json.ts
export const GET: APIRoute = ({ params, request }) => {
return new Response(JSON.stringify({
message: "This was a GET!"
})
)
}
export const POST: APIRoute = ({ request }) => {
return new Response(JSON.stringify({
message: "This was a POST!"
})
)
}
export const DELETE: APIRoute = ({ request }) => {
return new Response(JSON.stringify({
message: "This was a DELETE!"
})
)
}
export const ALL: APIRoute = ({ request }) => {
return new Response(JSON.stringify({
message: `This was a ${request.method}!`
})
)
}

在 SSR 模式下,request 属性返回一个引用当前请求的完全可用的 Request 对象。这允许你接受数据并检查标头:

¥In SSR mode, the request property returns a fully usable Request object that refers to the current request. This allows you to accept data and check headers:

src/pages/test-post.json.ts
export const POST: APIRoute = async ({ request }) => {
if (request.headers.get("Content-Type") === "application/json") {
const body = await request.json();
const name = body.name;
return new Response(JSON.stringify({
message: "Your name was: " + name
}), {
status: 200
})
}
return new Response(null, { status: 400 });
}

¥Redirects

端点上下文导出类似于 Astro.redirectredirect() 实用程序:

¥The endpoint context exports a redirect() utility similar to Astro.redirect:

src/pages/links/[id].js
import { getLinkUrl } from '../db';
export async function GET({ params, redirect }) {
const { id } = params;
const link = await getLinkUrl(id);
if (!link) {
return new Response(null, {
status: 404,
statusText: 'Not found'
});
}
return redirect(link, 307);
}
Astro 中文网 - 粤ICP备13048890号