跳转到内容

按需渲染适配器

Astro 允许你为部分或所有页面和端点选择按需渲染。这也被称为服务器端渲染 (SSR):在服务器上根据请求生成 HTML 页面,并将其发送给客户端。一个适配器被用来在服务器上运行你的项目并处理这些请求。

这种按需渲染允许你:

  • 在应用中实现登录状态的会话。
  • 从使用 fetch() 动态调用的 API 呈现数据。
  • 使用 适配器 将站点部署到主机。

如果你需要以下功能,可以考虑在你的 Astro 项目中启用按需服务器渲染:

  • API 端点:创建作为 API 端点的特定页面,用于数据库访问、身份验证和授权等任务,同时将敏感数据隐藏在服务端。

  • 受保护的页面:通过在服务器上处理用户访问,以限制对页面的访问。

  • 频繁更改的内容:生成单个页面时无需静态重建你的网站。当页面的内容频繁更新时,这是非常有用的,例如动态调用 fetch() 从 API 获取的数据。

Astro 为 Node.jsVercelNetlifyCloudflare 维护了官方的适配器。

在我们的集成目录中,你也可以找到更多社区维护的适配器(例如 Deno、SST、AWS)。

SSR 适配器

启用按需服务器渲染

段落标题 启用按需服务器渲染

Astro 的两种按需渲染输出模式(serverhybrid)都允许你通过尽可能预渲染单个路由来利用静态站点的性能优势,不论你是拥有一个完全动态的应用,还是大部分都是静态的网站,只需要为选定的路由进行按需渲染。

为了决定在你的项目中使用哪一个,请选择一个 output 选项,这个选项代表了你的大部分页面和路由将如何被渲染:

  • output: 'server':默认按需渲染。当你的网站或应用的大部分或全部应该在请求时进行服务器渲染时使用这个选项。任何单独的页面或端点都可以选择加入预渲染。
  • output: 'hybrid':默认预渲染为 HTML。在你的网站大部分应该是静态的时候使用这个选项。任何单独的页面或端点都可以选择退出预渲染。

因为服务器需要按需生成至少一些页面,所以这两种模式都需要你添加一个适配器来执行服务器功能。

要在 serverhybrid 模式下部署项目,你需要添加一个适配器。这是因为这两种模式都需要一个服务器 运行时:在服务器上运行代码以在请求时生成页面的环境。每个适配器都允许 Astro 输出一个在特定运行时(如 Vercel、Netlify 或 Cloudflare)上运行你的项目的脚本。

你可以在我们的 集成目录 中找到官方和社区的适配器。然后选择与你的 部署环境 相对应的适配器。

你可以使用以下 astro add 命令添加任何 由 Astro 维护的官方适配器。这将会一步到位地完成适配器的安装,并对 astro.config.mjs 文件进行适当的修改。例如,要安装 Vercel 适配器,请运行:

终端窗口
npx astro add vercel

你也可以通过手动安装包并更新 astro.config.mjs 自己添加适配器。例如,要手动安装 Vercel 适配器:

  1. 使用你首选的包管理器将适配器安装到你的项目依赖项:

    终端窗口
    npm install @astrojs/vercel
  2. 添加一个适配器到你的 astro.config.mjs 文件的导入和默认导出,以及你想要的 output 模式:

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import vercel from '@astrojs/vercel/serverless';
    export default defineConfig({
    output: 'server',
    adapter: vercel(),
    });

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

配置 severhybrid 模式

段落标题 配置 sever 或 hybrid 模式

要启用按需渲染,必须将你的 output 配置为两种服务器渲染模式之一。

例如,要配置一个高度动态的应用,其中每个页面默认都由服务器按需渲染,将 output: 'server' 添加到你的 Astro 配置中:

astro.config.mjs
import { defineConfig } from 'astro/config';
import node from "@astrojs/node";
export default defineConfig({
output: 'server',
adapter: node({
mode: "standalone"
})
});

server 模式中选择加入预渲染

段落标题 在 server 模式中选择加入预渲染

对于大部分以 output: server 配置的服务器渲染应用,添加 export const prerender = true 到任何页面或路由,以预渲染一个静态页面或端点:

src/pages/mypage.astro
---
export const prerender = true;
// ...
---
<html>
<!-- 这里是静态的、预渲染的页面... -->
</html>
src/pages/mypage.mdx
---
layout: '../layouts/markdown.astro'
title: 'My page'
---
export const prerender = true;
# 这是我的静态的、预渲染的页面
src/pages/myendpoint.js
export const prerender = true;
export async function GET() {
return new Response(
JSON.stringify({
message: `这是我的静态端点`,
}),
);
}

hybrid 模式中选择退出预渲染

段落标题 在 hybrid 模式中选择退出预渲染

对于大部分以 output: hybrid 配置的静态网站,添加 export const prerender = false 到任何应该按需服务器渲染的文件:

src/pages/randomnumber.js
export const prerender = false;
export async function GET() {
let number = Math.random();
return new Response(
JSON.stringify({
number,
message: `这是一个随机数:${number}`,
}),
);
}

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

这是一个用于读取和修改单个 cookie 的工具方法。它允许你检查、设置、获取和删除 cookie。

下面的示例更新了页面显示的计数器的 cookie 值。

src/pages/index.astro
---
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>

在 API 参考中查看有关 Astro.cookiesAstroCookie 类型 的更多详细信息。

Astro.response 是一个标准 ResponseInit 对象。它可用于设置响应状态和标头。

下面的示例设置了当产品不存在时,产品列表页面的响应状态和状态文本:

src/pages/product/[id].astro
---
export const prerender = false; // 无需在 `server` 模式下
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// 没有找到任何产品
if(!product) {
Astro.response.status = 404;
Astro.response.statusText = 'Not found';
}
---
<html>
<!-- 你的页面... -->
</html>

你可以使用 Astro.response.headers 对象以设置标题:

src/pages/index.astro
---
Astro.response.headers.set('Cache-Control', 'public, max-age=3600');
---
<html>
<!-- 你的页面... -->
</html>

返回一个 Response 对象

段落标题 返回一个 Response 对象

你可以手动或使用 Astro.redirect 来通过按需渲染直接从任何页面返回一个 Response 对象。

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

src/pages/[id].astro
---
export const prerender = false; // 无需在 `server` 模式下
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// 没有找到任何产品
if (!product) {
return new Response(null, {
status: 404,
statusText: 'Not found'
});
}
// 该商品不再可用
if (!product.isAvailable) {
return Astro.redirect("/products", 301);
}
---
<html>
<!-- 你的页面... -->
</html>

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

serverhybrid 模式下,对于非静态生成的页面,你可以从这个对象中获取更多信息。

请求的标头可在 Astro.request.headers 上找到。这就像浏览器的 Request.headers。它是一个 标头 对象,你可以在其中检索标头,例如 cookie。

src/pages/index.astro
---
const cookie = Astro.request.headers.get('cookie');
// ...
---
<html>
<!-- 你的页面 -->
</html>

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

src/pages/index.astro
---
console.log(Astro.request.method) // GET (在浏览器中导航到时)
---

在 API 参考中查看有关 Astro.request 的更多详细信息。

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

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

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

贡献

你有什么想法?

社区