跳转到内容

按需渲染

你的 Astro 项目代码必须被渲染成 HTML,才能在 Web 上显示。

默认情况下,Astro 页面、路由和 API 端点将在构建时作为静态页面预渲染。但是,你可以选择在请求路由时,由服务器按需渲染部分或全部路由。

按需渲染的页面和路由是每次访问时生成的,并且可以为每个访问者定制。例如,一个按需渲染的页面可以向已登录的用户显示其账户信息,或显示最新更新的数据,而无需重新构建整个网站。

在服务器上按请求时间进行按需渲染也称为服务器端渲染(SSR)

要按需渲染任何页面,你需要添加一个适配器。每个适配器都允许 Astro 输出一个脚本,在特定的**运行时**上运行你的项目:即在服务器上运行代码以在页面被请求时生成页面的环境(例如 Netlify、Cloudflare)。

即使你的网站完全是静态的,并且你没有按需渲染任何页面,你也可能希望添加一个适配器。例如,Netlify 适配器可以启用 Netlify 的图像 CDN,而服务器岛屿需要安装适配器才能在组件上使用 server:defer

适配器

Astro 为 Node.jsNetlifyVercelCloudflare 维护官方适配器。你可以在我们的集成目录中找到官方和社区适配器。请选择与你的部署环境相对应的适配器。

你可以使用以下 astro add 命令添加任何由 Astro 维护的官方适配器集成。此命令将一步完成适配器的安装,并对你的 astro.config.mjs 文件进行适当的更改。

例如,要安装 Netlify 适配器,请运行

终端窗口
npx astro add netlify

你也可以通过安装 NPM 包(例如 @astrojs/netlify)并自己更新 astro.config.mjs 来手动添加适配器。

请注意,不同的适配器可能有不同的配置设置。请阅读每个适配器的文档,并在 astro.config.mjs 中为你选择的适配器应用任何必要的配置选项。

默认情况下,你的整个 Astro 网站将被预渲染,静态 HTML 页面将被发送到浏览器。但是,你可以选择在任何需要服务器渲染的路由上禁用预渲染,例如,检查 cookie 并显示个性化内容的页面。

首先,为你的服务器运行时添加一个适配器集成,以在你的 Astro 项目中启用按需服务器渲染。

然后,在你想要按需渲染的单个页面或端点的顶部添加 export const prerender = false。你网站的其余部分将保持为静态网站。

src/pages/page-rendered-on-demand.astro
---
export const prerender = false
---
<html>
<!--
This content will be server-rendered on demand!
Just add an adapter integration for a server runtime!
All other pages are statically-generated at build time!
-->
<html>

以下示例展示了如何禁用预渲染,以便每次访问端点时都显示一个随机数。

src/pages/randomnumber.js
export const prerender = false;
export async function GET() {
let number = Math.random();
return new Response(
JSON.stringify({
number,
message: `Here's a random number: ${number}`,
}),
);
}

对于**高度动态的应用程序**,在添加适配器后,你可以将构建输出配置设置为 output: 'server',以**默认服务器渲染所有页面**。这相当于在每个页面上都禁用了预渲染。

然后,如果需要,你可以选择预渲染任何不需要服务器执行的单个页面,例如隐私政策或关于页面。

src/pages/about-my-app.astro
---
export const prerender = true
---
<html>
<!--
`output: 'server'` is configured, but this page is static!
The rest of my site is rendered on demand!
-->
<html>

export const prerender = true 添加到任何页面或路由,以预渲染静态页面或端点。

src/pages/myendpoint.js
export const prerender = true;
export async function GET() {
return new Response(
JSON.stringify({
message: `This is my static endpoint`,
}),
);
}
有关output 设置的更多信息,请参见配置参考。

通过 HTML 流式传输,文档被分解成块,按顺序通过网络发送,并按该顺序在页面上渲染。Astro 在按需渲染中使用 HTML 流式传输,在渲染每个组件时将其发送到浏览器。这可以确保用户尽快看到你的 HTML,尽管网络条件可能导致大文档下载缓慢,而等待数据获取可能会阻塞页面渲染。

按需渲染的页面或 API 端点可以检查、设置、获取和删除 cookie。

下面的示例更新了用于页面浏览计数器的 cookie 的值。

src/pages/index.astro
---
export const prerender = false; // Not needed in 'server' mode
let counter = 0
if (Astro.cookies.has('counter')) {
const cookie = Astro.cookies.get('counter')
const value = cookie?.number()
if (value !== undefined && !isNaN(value)) counter = value + 1
}
Astro.cookies.set('counter', String(counter))
---
<html>
<h1>Counter = {counter}</h1>
</html>

有关 Astro.cookiesAstroCookie 类型的更多详细信息,请参见 API 参考。

Astro.response 是一个标准的 ResponseInit 对象。它可以用来设置响应状态和头信息。

下面的示例在产品不存在时为产品页面设置了响应状态和状态文本。

src/pages/product/[id].astro
---
export const prerender = false; // Not needed in 'server' mode
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// No product found
if (!product) {
Astro.response.status = 404;
Astro.response.statusText = 'Not found';
}
---
<html>
<!-- Page here... -->
</html>

你可以使用 Astro.response.headers 对象设置头信息。

src/pages/index.astro
---
export const prerender = false; // Not needed in 'server' mode
Astro.response.headers.set('Cache-Control', 'public, max-age=3600');
---
<html>
<!-- Page here... -->
</html>

你也可以从任何使用按需渲染的页面直接返回一个 Response 对象,可以手动返回,也可以使用Astro.redirect

下面的示例在一个动态页面上查询数据库中的 ID,如果产品不存在,则返回 404;如果产品不再可用,则将用户重定向到另一个页面;或者显示产品。

src/pages/product/[id].astro
---
export const prerender = false; // Not needed in 'server' mode
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// No product found
if (!product) {
return new Response(null, {
status: 404,
statusText: 'Not found'
});
}
// The product is no longer available
if (!product.isAvailable) {
return Astro.redirect("/products", 301);
}
---
<html>
<!-- Page here... -->
</html>

Astro.request 是一个标准的 Request 对象。它可以用来获取请求的 urlheadersmethod,甚至请求体。

对于非静态生成的页面,你可以从此对象访问附加信息。

请求的头信息在 Astro.request.headers 上可用。这就像浏览器的 Request.headers。它是一个 Headers 对象,你可以从中检索诸如 cookie 之类的头信息。

src/pages/index.astro
---
export const prerender = false; // Not needed in 'server' mode
const cookie = Astro.request.headers.get('cookie');
// ...
---
<html>
<!-- Page here... -->
</html>

请求中使用的 HTTP 方法可通过 Astro.request.method 获得。这就像浏览器的 Request.method。它返回请求中使用的 HTTP 方法的字符串表示形式。

src/pages/index.astro
---
export const prerender = false; // Not needed in 'server' mode
console.log(Astro.request.method) // GET (when navigated to in the browser)
---

有关 Astro.request 的更多详细信息,请参见 API 参考。

服务器端点,也称为 **API 路由**,是从 src/pages/ 文件夹中的 .js.ts 文件导出的一个特殊函数。作为按需服务器端渲染的一个强大功能,API 路由能够在服务器上安全地执行代码。

该函数接收一个端点上下文并返回一个 Response

要了解更多信息,请参阅我们的端点指南

贡献 社区 赞助