Astro 的自定义端点可以返回 JSON、图像、RSS 或其他数据。端点定义与页面路由放在同一目录体系中,但由 JavaScript 或 TypeScript 函数返回 Response,而不是由组件生成 HTML。
静态站点在构建时调用端点,生成可直接托管的文件。按需渲染的服务器端点则在请求到来时运行,可以读取请求正文、设置状态码和响应头,并访问服务器端的数据。两种端点的定义方式相近,调用时机和可用上下文有所不同。
静态文件端点
在 src/pages 中添加 .js 或 .ts 文件,即可定义端点。构建时会移除这两个源代码扩展名,因此文件名还需包含目标数据的扩展名。例如,src/pages/data.json.ts 对应 /data.json。
端点导出 GET 函数,可以是异步函数。Astro 向它传入具有类似 Astro 全局属性的上下文对象,并在构建时将返回的 Response 正文写入文件。
下面是官方中文页面的 src/pages/builtwith.json.ts 示例:
// 输出:/builtwith.json
export function GET({ params, request }) {
return new Response(
JSON.stringify({
name: "Astro",
url: "https://astro.build/",
}),
);
}
从 Astro v3.0 起,返回的 Response 不再需要 encoding 属性。生成二进制 PNG 时,可以直接返回 ArrayBuffer。官方中文页面的 src/pages/astro-logo.png.ts 示例保留如下,其中官方资源地址是实际代码的一部分:
export async function GET({ params, request }) {
const response = await fetch(
"https://docs.astro.build/assets/full-logo-light.png",
);
return new Response(await response.arrayBuffer());
}
可以用 APIRoute 类型约束端点函数。中文页面的以下代码只是类型结构示意,{...} 并非可直接执行的完整函数体:
import type { APIRoute } from "astro";
export const GET: APIRoute = async ({ params, request }) => {...}
当前官方英文页面已采用 satisfies APIRoute 写法来检查函数的类型,后面的修订示例会展示完整形式。另外,英文页面补充说明:URL 含文件扩展名的端点只能通过不带尾斜杠的地址访问,例如 /sitemap.xml;尾斜杠配置不会使 /sitemap.xml/ 变成同一个有效端点。
params 与静态动态路由
端点支持与页面相同的动态路由方式。用方括号在文件名中声明参数,并导出 getStaticPaths() 来指定构建时应生成哪些路径。端点函数通过 params 读取参数。
官方中文页面的 src/pages/api/[id].json.ts 为:
import type { APIRoute } from "astro";
const usernames = ["张三", "李四", "王五", "赵六"];
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" } },
];
}
这会在构建时产生 /api/0.json、/api/1.json、/api/2.json 和 /api/3.json。getStaticPaths() 中的参数以字符串提供;中文示例直接拿 params.id 索引数组,在严格 TypeScript 检查中需要留意字符串或未定义值的类型问题。
当前英文文档修订。 同日核对的官方英文示例已显式将参数转成数字,并采用 satisfies APIRoute。下面是该修订的完整示例,作为上面中文示例的更新参照:
import type { APIRoute } from "astro";
const usernames = ["Sarah", "Chris", "Yan", "Elian"];
export const GET = (({ params, request }) => {
const id = Number(params.id);
return new Response(
JSON.stringify({
name: usernames[id],
}),
);
}) satisfies APIRoute;
export function getStaticPaths() {
return [
{ params: { id: "0" } },
{ params: { id: "1" } },
{ params: { id: "2" } },
{ params: { id: "3" } },
];
}
这里没有添加越界或非法 ID 的运行时检查;在这组静态路径中,构建输入由 getStaticPaths() 控制。如果改为接收任意客户端参数的服务器端点,仍应自行验证数值和索引范围。
中文页面目前笼统写“端点不支持 props”,但当前 英文端点文档 已明确区分:静态模式可以通过 getStaticPaths() 给端点传递 props;按需渲染的端点不支持这种传递方式。 此处按现行英文说明修正范围,不沿用中文段落中过宽的限制。
静态模式下的 request
所有端点都会收到 request 属性,但静态模式只能使用 request.url。它给出当前端点的完整 URL,用法与页面中的 Astro.request.url 相同。
官方中文页面的 src/pages/request-path.json.ts 示例返回 URL 的路径部分:
import type { APIRoute } from "astro";
export const GET: APIRoute = ({ params, request }) => {
return new Response(
JSON.stringify({
path: new URL(request.url).pathname,
}),
);
};
这段代码在静态模式下处理的是构建时的 URL。不能因为函数签名里有 request,就把它当成每一位访客的实时请求。
服务器端点与按需渲染
静态文件端点中的定义方式也适用于服务器端点:导出 GET,接收上下文,返回 Response。区别是按需渲染在请求到来时运行端点,因此可以读取即时数据、处理 API 请求并执行服务器端逻辑。
在 server 模式中,路由默认按需渲染。在 static 模式中,需在每个希望动态处理的端点导出 export const prerender = false,避免预渲染。测试这些示例前,应依照官方 按需渲染指南 配置所需适配器和部署环境。
服务器端点可以直接读取动态路由的 params,不必导出 getStaticPaths()。返回的 Response 可以设置状态码和响应头。官方中文页面的 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。如果示例的数据库查询返回产品,端点以 200 和 JSON 响应;没有产品时返回 404。getProduct 是由项目提供的函数,原页面没有给出其数据库实现,因此这段示例不能独立完成数据库访问。
返回二进制数据
服务器端点返回图像时应明确设置媒体类型;当前英文页面进一步限定为某些提供商要求此响应头。中文页面的 PNG 示例为:
export async function GET({ params, request }) {
const response = await fetch(
"https://docs.astro.build/assets/full-logo-light.png",
);
const buffer = Buffer.from(await response.arrayBuffer());
return new Response(buffer, {
headers: { "Content-Type": "image/png" },
});
}
这里使用了 Node.js 的 Buffer。当前英文示例注明,类型安全需要依赖中有 @types/node;其他运行时或适配器不一定提供相同的 Node.js 全局对象,应按其能力处理二进制数据。示例未检查上游 fetch 的状态码,也未提供错误处理,本次没有验证资源下载或部署兼容性。
按 HTTP 方法分发请求
除 GET 外,还可以导出以其他 HTTP 方法命名的函数。请求到来时,Astro 根据方法选择对应导出。ALL 用于处理没有同名导出的其他方法;没有匹配处理函数时,文档说明会进入网站的 404 处理。
官方中文页面的 src/pages/methods.json.ts 如下。代码引用了 APIRoute,单独保存这个文件时还需补上前文的 import type { APIRoute } from "astro";;原中文代码块没有该行,这里保留原内容并明确这一依赖。
export const GET: APIRoute = ({ params, request }) => {
return new Response(
JSON.stringify({
message: "这是个 GET 请求!",
}),
);
};
export const POST: APIRoute = ({ request }) => {
return new Response(
JSON.stringify({
message: "这是个 POST 请求!",
}),
);
};
export const DELETE: APIRoute = ({ request }) => {
return new Response(
JSON.stringify({
message: "这是个 DELETE 请求!",
}),
);
};
export const ALL: APIRoute = ({ request }) => {
return new Response(
JSON.stringify({
message: `这是个 ${request.method} 请求!`,
}),
);
};
如果有 GET 而没有 HEAD,Astro 会调用 GET 来处理 HEAD,并去掉响应正文。相关官方操作指南包括 校验验证码 和 使用 API 路由构建表单。
读取服务器请求
按需渲染时,request 是代表当前客户端请求的完整 Request 对象,可以检查请求头并读取正文。官方中文页面的 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 });
};
同样,独立 TypeScript 文件需导入 APIRoute。这是读取 JSON 的教学示例:它精确比较 Content-Type,因此不会接受 application/json; charset=utf-8 这样的带参数值;无效 JSON 也可能使 request.json() 抛出异常。实际端点还需按业务要求处理内容类型、正文大小、字段验证及错误,并在需要时认证调用者。上述原始代码并未实现这些功能,不能将它描述为完整生产接口。
重定向
端点上下文具有类似 Astro.redirect 的 redirect() 工具。中文页面在这一段却使用 Web Response.redirect(),两者的调用位置不同。先保留中文页面的 src/pages/links/[id].js 完整示例:
import { getLinkUrl } from "../db";
export async function GET({ params }) {
const { id } = params;
const link = await getLinkUrl(id);
if (!link) {
return new Response(null, {
status: 404,
statusText: "Not found"
});
}
return Response.redirect(link, 307);
}
getLinkUrl 需由项目实现,并保证导入路径与该文件的位置相符;文档没有提供链接数据库。本例对不存在的链接返回 404,存在时生成状态码为 307 的重定向响应。
当前英文文档修订。 当前英文示例从上下文解构 redirect,并用它返回响应,完整形式为:
import type { APIRoute } from "astro";
import { getLinkUrl } from "../db";
export const GET = (async ({ 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);
}) satisfies APIRoute;
这个修订更直接地对应“使用端点上下文工具”的说明。其中的 import type 和 satisfies 是 TypeScript 语法;英文页面仍将此例的文件名标为 .js,实际采用该类型写法时应使用 .ts,或在 JavaScript 文件中移除类型语法,不能原样将它当成普通 JavaScript。重定向目标的合法性及业务权限仍由项目决定。本次没有执行数据库访问、发送表单、构建 Astro 项目或验证重定向运行结果。
来源、许可与修改说明
本文完整整理 Astro 文档贡献者的现有官方中文 API 端点 主要正文与全部 10 个代码块,并核对 当前英文 Endpoints 文档,核对日期为 2026-10-03。它是官方中文内容的修订整理,未将已有中文文档宣称为本次新译或独立原创。
修改包括章节表述、示例依赖和未实现功能的说明,以及现行英文文档的文件扩展名尾斜杠规则、静态 props 范围、Number(params.id)、satisfies APIRoute、Node.js 类型依赖和上下文 redirect 用法。保留中文原例,另加入两段已明确标注的当前英文代码;没有虚构运行结果。原文广告、赞助卡片、导航和装饰图标不属于教学正文,未收录。
Astro 文档仓库的 LICENSE 为 MIT License。以下保留完整许可及版权声明:
MIT License
Copyright (c) 2022 withastro
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.











暂无评论内容