你的 Astro 项目代码必须经过渲染生成 HTML 才能在网页上显示。
默认情况下,Astro 的页面、路由和 API 端点会在构建时预先渲染为静态页面。但你可以选择让部分或全部路由在请求时由服务器进行按需渲染。
按需渲染的页面和路由会在每次访问时生成,并可为每个访客定制内容。例如,按需渲染的页面可以向已登录用户显示账户信息或展示实时更新的数据,而无需重新构建整个网站。
在请求时由服务端进行的按需渲染也被称为服务端渲染(SSR)。
服务器适配器
要实现页面按需渲染,需要添加适配器。每个适配器允许 Astro 输出可在特定运行时环境运行的脚本(如 Netlify、Cloudflare),这些环境会在服务器上执行代码以响应请求生成页面。
即使你的站点完全静态且不需要按需渲染任何页面,也建议添加适配器。例如,Netlify 适配器可启用 Netlify 的图片 CDN,而服务端群岛需要安装适配器才能在组件上使用 server:defer。
Astro 为 Node.js、Netlify、Vercel 和 Cloudflare 维护官方适配器。你可以在集成目录找到官方和社区适配器,选择与你部署环境匹配的适配器。
官方 SSR 适配器包括:@astrojs/cloudflare、@astrojs/netlify、@astrojs/node 和 @astrojs/vercel。
添加适配器
使用以下 astro add 命令可添加任何由 Astro 维护的官方适配器集成。该命令将自动安装适配器并修改 astro.config.mjs 文件。
例如,安装 Netlify 适配器可运行:
npm:
npx astro add netlify
pnpm:
pnpm astro add netlify
Yarn:
yarn 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>
<!--
此内容将按需服务端渲染!
只需为服务器运行时添加适配器集成!
其他所有页面仍会在构建时静态生成!
-->
<html>
原文这段示例末尾写作 <html>,不是闭合标签;本稿逐字保留原例。实际页面应使用 </html> 结束文档。
以下示例通过禁用预渲染,使端点每次被访问时生成随机数:
src/pages/randomnumber.js:
export const prerender = false;
export async function GET() {
let number = Math.random();
return new Response(
JSON.stringify({
number,
message: `这是一个随机数:${number}`,
}),
);
}
'server' 模式
对于高度动态的应用,在添加适配器后,可以将构建输出配置设为 output: 'server',来默认按需服务端渲染所有页面。这等同于在所有页面上禁用预渲染。
然后,你可以选择对不需要服务端执行的页面(如隐私政策、关于页面)启用预渲染:
src/pages/about-my-app.astro:
---
export const prerender = true
---
<html>
<!--
配置了 `output: 'server'`,但此页面是静态的!
站点其余部分将按需渲染!
-->
<html>
这段原例也以 <html> 结束;实际页面应改为闭合标签 </html>。
通过向任意页面或路由添加 export const prerender = true 可预渲染静态页面或端点:
src/pages/myendpoint.js:
export const prerender = true;
export async function GET() {
return new Response(
JSON.stringify({
message: `这是静态端点`,
}),
);
}
建议从默认的 'static' 模式开始,直到确定大部分或全部页面需要按需渲染!这能确保站点保持最佳性能,静态内容无需依赖服务端渲染。
'server' 输出模式不会带来额外功能,仅切换默认渲染行为。查看配置参考中关于 output 设置的更多信息。
按需渲染特性
HTML 流式传输
通过 HTML 流式传输,文档会被拆分为多个片段按顺序发送,并在浏览器中按序渲染。Astro 在按需渲染中使用此技术,逐个组件发送到浏览器。这能确保用户尽快看到内容,但网络状况可能导致大文档加载缓慢,数据获取也可能阻塞页面渲染。
修改响应标头的功能仅能在页面级别使用,无法在组件中使用,包括布局组件。当 Astro 执行你的组件代码时,响应头已经被发送,无法再进行修改。
Cookies
按需渲染的页面或 API 端点可以检查、设置、获取和删除 cookie。以下示例更新页面访问计数器的 cookie 值:
src/pages/index.astro:
---
export const prerender = false; // 'server' 模式下无需此设置
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}</h1>
</html>
更多关于 Astro.cookies 和 AstroCookie 类型的细节请参阅 API 参考。
Response
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
可以通过 Astro.response.headers 对象设置响应头:
src/pages/index.astro:
---
export const prerender = false; // 'server' 模式下无需此设置
Astro.response.headers.set('Cache-Control', 'public, max-age=3600');
---
<html>
<!-- 页面内容... -->
</html>
示例中的 public 缓存头适用于允许公开缓存的响应;包含账户、cookie 个性化信息等用户专属内容的页面,不应直接照用。
返回 Response 对象
在按需渲染的页面中,可以直接返回 Response 对象,或使用 Astro.redirect 进行重定向。
以下示例在动态页面中查找数据库中的 ID,如果产品不存在则返回 404,如果产品不再可用则重定向用户到其他页面,或者显示产品信息:
src/pages/product/[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: '未找到'
});
}
// 产品不再可用
if (!product.isAvailable) {
return Astro.redirect("/products", 301);
}
---
<html>
<!-- 页面内容... -->
</html>
Request
Astro.request 是标准的 Request 对象,可用于获取 url、headers、method,甚至请求的 body。在非静态生成的页面中,可以通过该对象获取额外信息。
Astro.request.headers
请求标头可通过 Astro.request.headers 获取,其行为与浏览器的 Request.headers 一致。这是一个 Headers 对象,可用来获取 cookie 等标头信息。
src/pages/index.astro:
---
export const prerender = false; // 'server' 模式下无需此设置
const cookie = Astro.request.headers.get('cookie');
// ...
---
<html>
<!-- 页面内容... -->
</html>
Astro.request.method
请求的 HTTP 方法可通过 Astro.request.method 获取,其行为与浏览器的 Request.method 一致。它返回请求中使用的 HTTP 方法的字符串表示。
src/pages/index.astro:
---
export const prerender = false; // 'server' 模式下无需此设置
console.log(Astro.request.method) // GET(浏览器访问时)
---
更多关于 Astro.request 的细节请参阅 API 参考。
服务器端点
服务器端点(也称 API 路由)是位于 src/pages/ 目录下 .js 或 .ts 文件中导出的特殊函数。作为服务端按需渲染的强大特性,API 路由能安全地在服务端执行代码。
该函数接收端点上下文并返回 Response 对象。更多信息请参阅端点指南。
来源:按需渲染 | Docs。原文作者:Astro 文档贡献者。许可:MIT。中文内容和版式作了调整。
MIT 许可全文
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.











暂无评论内容