会话
Added in:
astro@5.7.0
新
会话用于在 按需渲染的页面 的请求之间共享数据。
¥Sessions are used to share data between requests for on-demand rendered pages.
与 cookies
不同,会话存储在服务器上,因此你可以存储大量数据,而无需担心大小限制或安全问题。它们可用于存储用户数据、购物车和表单状态等内容,并且无需任何客户端 JavaScript 即可工作:
¥Unlike cookies
, sessions are stored on the server, so you can store larger amounts of data without worrying about size limits or security issues. They are useful for storing things like user data, shopping carts, and form state, and they work without any client-side JavaScript:
---export const prerender = false; // Not needed with 'server' outputconst cart = await Astro.session?.get('cart');---
<a href="/checkout">🛒 {cart?.length ?? 0} items</a>
配置会话
标题部分 配置会话¥Configuring sessions
会话需要存储驱动程序来存储会话数据。Node、Cloudflare 和 Netlify 适配器会自动为你配置默认驱动程序,但其他适配器目前要求你配置 手动指定驱动程序。
¥Sessions require a storage driver to store the session data. The Node, Cloudflare, and Netlify adapters automatically configure a default driver for you, but other adapters currently require you to specify a driver manually.
{ adapter: vercel(), session: { driver: "redis", }, }
See the session
configuration option for more details on setting a storage driver, and other configurable options.
与会话数据交互
标题部分 与会话数据交互¥Interacting with session data
session
对象 允许你与存储的用户状态(例如,将商品添加到购物车)和会话 ID(例如,在注销时删除会话 ID Cookie)进行交互。该对象在你的 Astro 组件和页面中可作为 Astro.session
访问,在 API 端点、中间件和操作中可作为 context.session
对象访问。
¥The session
object allows you to interact with the stored user state (e.g. adding items to a shopping cart) and the session ID (e.g. deleting the session ID cookie when logging out). The object is accessible as Astro.session
in your Astro components and pages and as context.session
object in API endpoints, middleware, and actions.
会话在首次使用时自动生成,可以随时使用 session.regenerate()
重新生成或使用 session.destroy()
销毁。
¥The session is generated automatically when it is first used and can be regenerated at any time with session.regenerate()
or destroyed with session.destroy()
.
在许多用例中,你只需要使用 session.get()
和 session.set()
。
¥For many use cases, you will only need to use session.get()
and session.set()
.
See the Sessions API reference for more details.
Astro 组件和页面
标题部分 Astro 组件和页面¥Astro components and pages
在 .astro
组件和页面中,你可以通过全局 Astro
对象访问会话对象。例如,要显示购物车中的商品数量:
¥In .astro
components and pages, you can access the session object via the global Astro
object. For example, to display the number of items in a shopping cart:
---export const prerender = false; // Not needed with 'server' outputconst cart = await Astro.session?.get('cart');---
<a href="/checkout">🛒 {cart?.length ?? 0} items</a>
API 端点
标题部分 API 端点¥API endpoints
在 API 端点中,会话对象在 context
对象上可用。例如,要将商品添加到购物车:
¥In API endpoints, the session object is available on the context
object. For example, to add an item to a shopping cart:
export async function POST(context: APIContext) { const cart = await context.session?.get('cart') || []; const data = await context.request.json<{ item: string }>(); if(!data?.item) { return new Response('Item is required', { status: 400 }); } cart.push(data.item); await context.session?.set('cart', cart); return Response.json(cart);}
操作
标题部分 操作¥Actions
在操作中,会话对象在 context
对象上可用。例如,要将商品添加到购物车:
¥In actions, the session object is available on the context
object. For example, to add an item to a shopping cart:
import { defineAction } from 'astro:actions';import { z } from 'astro:schema';
export const server = { addToCart: defineAction({ input: z.object({ productId: z.string() }), handler: async (input, context) => { const cart = await context.session?.get('cart'); cart.push(input.productId); await context.session?.set('cart', cart); return cart; }, }),};
中间件
标题部分 中间件¥Middleware
在中间件中,会话对象在 context
对象上可用。例如,要在会话中设置上次访问时间:
¥In middleware, the session object is available on the context
object. For example, to set the last visit time in the session:
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware(async (context, next) => { context.session?.set('lastVisit', new Date()); return next();});
会话数据类型
标题部分 会话数据类型¥Session data types
默认情况下,会话数据是未键入的,你可以将任意数据存储在任何键中。使用 devalue 对值进行序列化和反序列化,这与内容集合和操作中使用的库相同。这意味着支持的类型相同,包括字符串、数字、Date
、Map
、Set
、URL
、数组和普通对象。
¥By default session data is untyped, and you can store arbitrary data in any key. Values are serialized and deserialized using devalue, which is the same library used in content collections and actions. This means that supported types are the same, and include strings, numbers, Date
, Map
, Set
, URL
, arrays, and plain objects.
你可以通过创建 src/env.d.ts
文件并添加 App.SessionData
类型的声明来为你的会话数据定义 TypeScript 类型:
¥You can optionally define TypeScript types for your session data by creating a src/env.d.ts
file and adding a declaration for the App.SessionData
type:
declare namespace App { interface SessionData { user: { id: string; name: string; }; cart: string[]; }}
这将允许你在编辑器中使用类型检查和自动补齐访问会话数据:
¥This will allow you to access the session data with type-checking and auto-completion in your editor:
---const cart = await Astro.session?.get('cart');// const cart: string[] | undefined
const something = await Astro.session?.get('something');// const something: any
Astro.session?.set('user', { id: 1, name: 'Houston' });// Error: Argument of type '{ id: number; name: string }' is not assignable to parameter of type '{ id: string; name: string; }'.---