实验会话
类型:boolean
默认:false
¥Type: boolean
Default: false
astro@5.1.0
会话用于在 按需渲染的页面 请求之间存储用户状态。
¥Sessions are used to store user state between requests for on-demand rendered pages.
此实验性功能允许你存储和访问登录状态、购物车内容或其他用户特定数据等项目:
¥This experimental feature allows you to store and access items such as login status, shopping cart contents, or other user-specific data:
---export const prerender = false; // Not needed with 'server' outputconst cart = await Astro.session.get('cart');---
<a href="/checkout">🛒 {cart?.length ?? 0} items</a>
会话依赖 可配置会话 driver
将数据存储在 session
对象上。会话 cookie 存储识别会话 ID。
¥Sessions rely on a configurable session driver
to store data on the session
object. A session cookie stores an identifying session ID.
session
对象 允许你与存储的用户状态(例如,将商品添加到购物车)和会话 ID(例如,在注销时删除会话 ID cookie)进行交互。
¥The session
object allows you to interact with the stored user state (e.g. add items to a shopping cart) and the session ID (e.g. delete the session ID cookie when logging out).
启用实验会话
标题部分 启用实验会话¥Enabling experimental sessions
要启用会话,请将 experimental.session
标志设置为 true
。会话仅适用于具有按需渲染的页面,因此你需要支持按需渲染的 安装适配器,并确保在 Astro 配置中将使用会话的任何页面设置为 prerender: false
,或将 output
设置为 server
。
¥To enable sessions, set the experimental.session
flag to true
. Sessions only work on pages with on-demand rendering, so you need to install an adapter that supports on-demand rendering, and ensure that any pages that use sessions are set to prerender: false
, or output
is set to server
in the Astro config.
{ adapter: node({ mode: "standalone", }), experimental: { session: true, }, }
会话需要存储驱动程序来存储会话数据。Node 和 Netlify 适配器会自动为你配置默认驱动程序,但其他适配器当前需要你 手动指定驱动程序。你可以使用 来自 unstorage 的任何受支持的驱动程序。
¥Sessions require a storage driver to store the session data. The Node and Netlify adapters automatically configure a default driver for you, but other adapters currently require you to specify a driver manually. You can use any supported driver from unstorage.
配置会话驱动程序
标题部分 配置会话驱动程序¥Configuring a session driver
如果你使用的适配器没有默认驱动程序,或者你想选择其他驱动程序,则可以使用 session
配置选项对其进行配置:
¥If you are using an adapter that doesn’t have a default driver, or if you want to choose a different driver, you can configure it using the session
configuration option:
{ adapter: vercel(), session: { driver: "upstash", }, experimental: { session: true, }, }
使用与你的托管平台提供的存储功能(例如 Cloudflare KV 驱动程序 或 Deno KV 驱动程序)相对应的非存储 driver
名称配置 session.driver
。你还可以使用跨平台驱动程序,例如 Upstash 或 Redis。
¥Configure session.driver
with the unstorage driver
name that corresponds to the storage feature provided by your hosting platform, such as the Cloudflare KV driver or the Deno KV driver. You can also use a cross-platform driver such as Upstash or Redis.
驱动程序选项
标题部分 驱动程序选项¥Driver options
你还可以在单独的 session.options
对象中将任何可用选项传递给 unstorage 驱动程序。有关可用选项,请参阅你选择的驱动程序的文档。
¥You can also pass any available options to the unstorage driver in a separate session.options
object. See your chosen driver’s documentation for available options.
以下示例设置了 base
前缀 ("sessions"
) 以用于 Upstash 中的所有密钥:
¥The following example sets a base
prefix ("sessions"
) to use for all keys in Upstash:
{ adapter: vercel(), session: { driver: "upstash", options: { base: "sessions", }, }, experimental: { session: true, }, }
其他会话选项
标题部分 其他会话选项¥Other session options
你可以在 session
对象中为会话配置其他选项。
¥You can configure additional options for sessions in the session
object.
session.cookie
标题部分 session.cookie类型:string
| object
默认值:astro-session
¥Type: string
| object
Default: astro-session
配置会话 cookie。在生成会话时,此 cookie 会在响应中设置。cookie 中不存储任何实际用户数据 - 仅存储用于识别用户会话的 ID。session.cookie
选项可用于设置此 cookie 的选项。你可以提供一个 string
(将用作 cookie 名称)或一个允许其他选项的对象:
¥Configures the session cookie. This cookie is set in the response when a session is generated. No actual user data is stored in the cookie – just an ID that is used to identify a user’s session. The session.cookie
option can be used to set options for this cookie. You can either provide a string
, which will be used as the cookie name, or an object which allows additional options:
{ session: { // If set to a string, this will be used as the cookie name // cookie: "my-session-id", // If set to an object, this will allow advanced options to be set cookie: { name: "my-session-id" sameSite: "Strict", }, } }
session.ttl
标题部分 session.ttl类型:number
默认:undefined
¥Type: number
Default: undefined
允许你访问构建中使用的 Vite 配置的对象。
¥An optional default time-to-live expiration period for session values, in seconds.
默认情况下,会话值会一直存在,直到它们被删除或会话被销毁,并且不会因为特定时间过去而自动过期。设置 session.ttl
以添加会话值的默认到期期限。将 ttl
选项传递给 session.set()
将覆盖该单个条目的全局默认值。
¥By default, session values persist until they are deleted or the session is destroyed, and do not automatically expire because a particular amount of time has passed. Set session.ttl
to add a default expiration period for your session values. Passing a ttl
option to session.set()
will override the global default for that individual entry.
{ session: { ttl: 60 * 60, // 1 hour } }
使用会话
标题部分 使用会话¥Using sessions
配置驱动程序后,你可以使用 session
对象与会话进行交互。该对象可在 Astro 组件和页面中作为 Astro.session
访问,也可在 API 端点、中间件和操作中的 context
对象上访问。API 在所有情况下都是相同的。
¥Once you have configured a driver, you can use the session
object to interact with the session. The object is accessible as Astro.session
in your Astro components and pages and on the context
object in API endpoints, middleware and actions. The API is the same in all cases.
会话在首次使用时自动生成,可以随时使用 Astro.session.regenerate()
重新生成或使用 Astro.session.destroy()
销毁。
¥The session is generated automatically when it is first used and can be regenerated at any time with Astro.session.regenerate()
or destroyed with Astro.session.destroy()
.
在大多数情况下,你只需要使用 Astro.session.get()
和 Astro.session.set()
。有关其他可用方法,请参阅 API 部分。
¥In most cases, you will only need to use Astro.session.get()
and Astro.session.set()
. For other available methods, see the API section.
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:
import type { APIContext } from 'astro';
export async function POST(req: Request, context: APIContext) { const cart = await context.session.get('cart'); cart.push(req.body.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; }'.---
会话 API
标题部分 会话 API¥Sessions API
会话在首次访问时会自动创建。会话对象在所有 Astro 上下文中都可用,包括组件、操作和 API 端点。在组件中,它通过全局 Astro
对象访问,在操作和 API 端点中,它可在 context
对象上使用。API 在所有情况下都是相同的。
¥Sessions are automatically created when they are first accessed. The session object is available in all Astro contexts, including components, actions, and API endpoints. In components, it is accessed via the global Astro
object, and in actions and API endpoints, it is available on the context
object. The API is the same in all cases.
session.get()
标题部分 session.get()类型:(key: string) => Promise<any>
¥Type: (key: string) => Promise<any>
返回会话中给定键的值。如果密钥不存在,则返回 undefined
。
¥Returns the value of the given key in the session. If the key does not exist, it returns undefined
.
session.set()
标题部分 session.set()类型:(key: string, value: any, options?: { ttl: number }) => void
¥Type: (key: string, value: any, options?: { ttl: number }) => void
设置会话中给定键的值。该值可以是任何可序列化的类型。此方法是同步的,值可立即检索,但直到请求结束时才会保存到后端。
¥Sets the value of the given key in the session. The value can be any serializable type. This method is synchronous and the value is immediately available for retrieval, but it is not saved to the backend until the end of the request.
session.regenerate()
标题部分 session.regenerate()类型:() => void
¥Type: () => void
重新生成会话 ID。最佳做法是在用户登录或提升其权限时调用此方法,以防止会话固定攻击。
¥Regenerates the session ID. Best practice is to call this when a user logs in or escalates their privileges, to prevent session fixation attacks.
session.destroy()
标题部分 session.destroy()类型:() => void
¥Type: () => void
销毁会话,从后端删除 cookie 和对象。当用户注销或其会话无效时,应调用此方法。
¥Destroys the session, deleting the cookie and the object from the backend. This should be called when a user logs out or their session is otherwise invalidated.
进一步阅读
标题部分 进一步阅读¥Further reading
有关完整详细信息和对此实验性 API 提供反馈,请参阅 会话 RFC。
¥For full details and to give feedback on this experimental API, see the Sessions RFC.
Reference