# @ayco/astro-resume 中文文档

规范地址：https://npmcn.com/package/%40ayco/astro-resume/

版本：1\.1\.1
npm 元数据更新时间：2026-08-12T18:07:17.319Z
中文译文更新时间：2026-11-08T05:21:58.886Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40ayco/astro-resume
原文对照：https://npmcn.com/package/%40ayco/astro-resume/?lang=original
项目主页：https://ayco.io/n/astro-resume
源码仓库：https://github.com/ayo-run/astro-resume

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：18.3 kB，6 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- 运行依赖：0 个
- peer 依赖：astro \>=4
- 首次发布：2023-07-16T10:21:58.920Z
- 最新版本发布：2026-08-12T18:07:16.914Z
- 近 30 天下载量：1895（2026-10-08 至 2026-11-06，npm 官方下载统计）
- 已发布版本数：40（近 12 个月 5 个）

## 中文简介

Astro 中的安全服务器对客户端数据

## 安装

```sh
npm install @ayco/astro-resume
```

也可以使用：`pnpm add @ayco/astro-resume`、`yarn add @ayco/astro-resume`、`bun add @ayco/astro-resume`

## README

# Astro 续作

[![Package information: NPM version](https://img.shields.io/npm/v/@ayco/astro-resume)](https://www.npmjs.com/package/@ayco/astro-resume) [![Package information: NPM license](https://img.shields.io/npm/l/@ayco/astro-resume)](https://www.npmjs.com/package/@ayco/astro-resume) [![Package information: NPM downloads](https://img.shields.io/npm/dt/@ayco/astro-resume)](https://www.npmjs.com/package/@ayco/astro-resume)

[![CI](https://github.com/ayo-run/astro-resume/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ayo-run/astro-resume/actions/workflows/ci.yml) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/ayo-run/astro-resume/badge)](https://scorecard.dev/viewer/?uri=github.com/ayo-run/astro-resume) [![Runtime dependencies](https://img.shields.io/badge/runtime%20dependencies-0-brightgreen)](https://www.npmjs.com/package/@ayco/astro-resume?activeTab=dependencies)

> \[! 警告\] **在V0吗? 升级.** 以前每个版本 `1.0.0` 将序列化的数据写入页面而不逃避 `<`因此,一个字符串包含 `</script>` 在数据中提早关闭元素,其余以 HTML 运行。 如果其中任何数据来自用户输入,则视其为可开发数据。 固定在 `1.0.0`,其唯一破碎的更改是 TypeScript 之一 — 见 [逃脱 & XSS](https://npmcn.com/package/%40ayco/astro-resume/#readme-escaping--xss) 财务报告和审定财务报表 [升级到 v1](https://npmcn.com/package/%40ayco/astro-resume/#readme-upgrading-to-v1)。 。 。 .

> \[!注\] **V1 中新建** —— 说 `deserialize<T>` 现在默认为 `unknown` 改为 `any`,所以没有类型参数的调用在读取结果属性时不再进行键入检查。 见 [升级到 v1](https://npmcn.com/package/%40ayco/astro-resume/#readme-upgrading-to-v1)。 。 。 .

用于序列化服务器数据供客户端使用的工具.

1.  `Serialize` - 需要Astro组件 `id` 财务报告和审定财务报表 `data`
2.  `deserialize()` - 用于客户端的功能 `id` 字符串并返回 `data` 对象

## 通过 npm 安装

在你身边 [天体](https://astro.build/) 项目:

```
npm i @ayco/astro-resume
```

需要Astro 4或更新.

## 使用量

基本原始数据的序列化和去序列化

```astro
---
import Serialize from "@ayco/astro-resume";

const data = {
    hello: 'world',
}
---

<Serialize id="my-data" data={data} />

<script>
import {deserialize} from '@ayco/astro-resume';
const data = deserialize('my-data');
console.log(data) // {hello: 'world'}
</script>

```

没有类型参数 `data` 实值 `unknown` 足够登入或传入,但不能读取属性。 说出要这样做的类型.

## 类型安全

`deserialize<T>()` 返回时 `T`,默认为 `unknown`。可以定义数据的类型,并在客户端脚本中使用.

```astro
---
import Serialize from "@ayco/astro-resume";

const data = {
    hello: 'world',
    isOkay: true
}
// define the type of data to be serialized
export type Data = typeof data;
---

<Serialize id="my-data" data={data} />

<script>
import {deserialize} from '@ayco/astro-resume';

/**
* reuse the type in the client
* assuming this component's name is `ThisComponent.astro`
*/
import type {Data} from './ThisComponent.astro';

const data = deserialize<Data>('my-data');

console.log(data) // {hello: 'world', isOkay: true}
</script>
```

自定义解析器已键入 `(serialized: string) => T`,同样的 `T` 呼叫回来。 这么说吧 `deserialize<Data>('my-data', parse)` 检查您的解析器是否生成 `Data`,以及 `deserialize('my-data', myParser)` 推断 `T` 从 `myParser` 而不是掉头 `unknown`。 。 。 .

## 将全部 Astro.props 传递给客户端

如果您需要将所有组件道具制成客户端脚本 :

```astro
---
import Serialize from "@ayco/astro-resume";
export interface Props {
    hello: string;
    isOkay: boolean;
}
---

<Serialize id="preferences" data={{...Astro.props}} />

<script>
import {deserialize} from '@ayco/astro-resume';
import type {Props} from './ThisComponent.astro';
const {hello, isOkay} = deserialize<Props>('preferences');
console.log(hello, isOkay);
</script>
```

## 将服务器数据序列化一次, 访问到任何地方

如果您共享了需要从服务器初始化并在客户端多个地方访问的数据,则可以使用 `Serialize` 一次和一次 `deserialize` 只要Astro组件在同一页中,它们就属于任何数量.

在这个例子中,一个 AppConfig 对象在index.astro 中被构建并序列化,在child Astro 组件中访问.

在索引.astro:

```astro
import Serialize from "@ayco/astro-resume";

const appConfig = {
    someClientSideKey: '1234hello',
}
export type AppConfig = typeof appConfig;
---

<Serialize id="app-config" data={appConfig} />
<Child />
```

在 Child.astro 中: (中文(简体) )

```astro
<h1>I'm a child. I have access to the appConfig in index!</h1>
<GrandChild />
<script>
import {deserialize} from '@ayco/astro-resume';
import type {AppConfig} from '..pages/index.astro';
const data = deserialize<AppConfig>('app-config');

// ... do something with the app config
</script>
```

在Grand Child.astro: (原始内容存档于2019-09-28)

```astro
<h1>I'm a grand child. I also have access to the appConfig in index!</h1>
<script>
import {deserialize} from '@ayco/astro-resume';
import type {AppConfig} from '..pages/index.astro';
const data = deserialize<AppConfig>('app-config');

// ... do something with the app config
</script>
```

## 使用自定义序列器和解析器

如果您想要选择更复杂的数据处理, 可以带自定义序列器/ 参数 .

以下是数据序列化的例子 `JSON.stringify` 无法使用 Rich Harris' (例如日期或 BigInt) [`devalue`](https://github.com/Rich-Harris/devalue)数字 :

```astro
---
import {stringify} from 'devalue';
import Serialize from "@ayco/astro-resume";
const data = {
    now: new Date(),
    age: BigInt('3218378192378')
}
export type Data = typeof data;
---

<Serialize data={data} id="my-data" use={stringify} />

<script>
import {parse} from 'devalue';
import {deserialize} from '@ayco/astro-resume';
import type {Data} from './index.astro';

const {age, now} = deserialize<Data>('my-data', parse);
console.log(typeof age); // 'bigint'
console.log(now instanceof Date); // true
</script>
```

注意自定义序列器的输出是写在页面的正文上,所以它必须自己逃出——见下文. `devalue` 已经 如果没有的话, `Serialize` 拒绝提供而不是运送突围.

## 逃脱 & XSS

序列化数据写入于 a `<script>` 元素,所以字符串类似 `</script><img src=x onerror=alert(1)>` 在数据中,否则会提前关闭该元素,让其余部分以 HTML 运行.

`Serialize` 避免这一切 `<` 输出为 `\u003c`这是有效的JSON字符串逃脱,所以没有损失.. `deserialize()` 原弦还给你 `</script` 绝对不能出现在序列有效载荷中.

```astro
<Serialize id="my-data" data={{evil: '</script><img src=x onerror=alert(1)>'}} />

<!-- renders as: -->
<script type="application/json" id="my-data">{"evil":"\u003c/script>\u003cimg src=x onerror=alert(1)>"}</script>
```

有两个限制值得了解:

1.  **自定义序列器不会为你逃脱.** 当你通过 `use`,它的返回值不作修改地写到页面上,这样一个发布自己格式的序列器就不会被损坏。 用一个逃跑的 `<` 本身 - [`devalue`](https://github.com/Rich-Harris/devalue) 已经.
    
    作为后援, `Serialize` 如果串行输出仍然包含 `</script`,因此一个无法逃避的序列器在渲染时会响亮地出故障,而不是运输XSS. 那张支票是定向的,不是HTML脚本的完整模型解析——一个能逃脱的序列器 `<` 仍然值得信赖.
    
2.  **这能保护有效载荷,而不是你用它做什么.** 数据你取出 `deserialize()` 回到DOM 仍然需要正常的护理 更喜欢 `textContent` 结束 `innerHTML`。 。 。 .
    

## 错误警告( W) `deserialize()`

这个 `deserialize()` 函数可以给出以下内容:

1.  **错误RR: 找不到匹配** - 没有 `JSON` 带有指定标识的脚本
2.  **ERR: 分析数据失败 `<id>`** - 发现一个脚本,但是 `JSON.parse` (或您的定制解析器) 扔在它的内容
3.  **警告: 多个匹配 `<id>`** - 有多个 `JSON` 用同一ID找到的脚本

抛出的错误将潜在的失败保留为 [`cause`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause)因此,真正的问题仍然存在,以检查:

```js
try {
  const data = deserialize<Data>('my-data');
} catch (err) {
  console.error(err.message); // astro-resume ERR: Failed to parse data for "my-data".
  console.error(err.cause);   // SyntaxError: Unexpected token ...
}
```

`Serialize` 在服务器上执行同样内容 : 如果您的数据无法被序列化, 则将“ 数据不可序列化 ” 与原始数据一起丢出 `TypeError` 圆形结构,或 `BigInt` 没有自定义序列器——作为 `cause`。 。 。 .

## 关于

这是一个快速而简单的模式,可以将序列化的信息嵌入到您的 HTML 中,并以客户端脚本提供. 这不需要客户端JS 直接将数据嵌入到您的HTML上.

这个 `Serialize` 组件会将数据写入 JSON 中 `<script type="application/json">` 用于按住字符串的元素.

这个 `deserialize()` 函数然后可以解析用于客户端脚本的值字符串.

还有一种模式 [在 Astro 文档中给出](https://docs.astro.build/en/guides/client-side-scripts/#pass-frontmatter-variables-to-scripts) 来使用自定义元素 `data-` 适当保护组件范围的道具。 它要求客户方联署材料.

## 贸易业务

其他一些框架本身会为你管理序列化的信息和ID, 但我们无法在Astro访问,因为我们并没有真正将一个框架传送到浏览器.

这很好,也是理想的(在我看来),因为我们知道HTML是如何形成的,以及我们正在向用户运送什么. 换句话说,我们必须自己去处理事情.

你必须管理身份证(即确保身份证是独一无二的),并了解这些证件是否具有特殊性 `deserialize()` 函数将爬行整个文档,其性能成本将视您的 HTML 大小而定.

身份证本身可以是任何字符串. 无效的 CSS 标识符 - `my.data`, (中文(简体) ), `ns:data[0]`, (中文(简体) ), `1data` 被逃脱 `CSS.escape` 在检查之前,所以他们决心而不是默默地不匹配.

## 发展

此寄存器是一个 pnpm 工作空间 : `package/` 是已发布的软件包,并且 `demo/` 是一个消耗它的Astro网站.

```
pnpm install
pnpm dev      # run the demo site
pnpm lint     # eslint
pnpm test     # vitest (happy-dom for deserialize, Astro Container API for Serialize)
pnpm check    # astro check on the demo
pnpm release  # bumpp: bump package/package.json, commit, tag, push
```

`pnpm lint`, (中文(简体) ), `pnpm test` 财务报告和审定财务报表 `pnpm check` 是三个命令 CI 运行.

## 升级到 v1

**断裂变化:** `deserialize<T>` 默认为 `unknown` 改为 `any`。 。 。 .

```ts
// v0 — `data` was `any`, so this compiled and checked nothing
const data = deserialize('my-data');
data.hello.toUpperCase();

// v1 — name the type
const data = deserialize<Data>('my-data');
data.hello.toUpperCase();
```

要求只移动价值——记录价值,将其交给别的东西——保持工作不受影响。 调用到结果需要类型参数或缩小检查。 现已输入自定义解析器 `(serialized: string) => T` 而不是返回 `any`,所以通过一个也给 `T` 某种可以推断的东西.

V1 中的其他所有内容都是向后兼容的 :

-   **安全修补——即使没有类型错误也要升级的原因.** `<` 以 `\u003c`,因此数据无法再从 `<script>` 键。 v0完全没有逃脱,所以包含 `</script>` 可作为 HTML 运行 。 这改变了页面上的字节,而不是返回的值。 见 [逃脱 & XSS](https://npmcn.com/package/%40ayco/astro-resume/#readme-escaping--xss)。 。 。 .
-   无法使用 CSS 标识符的ID 将使用 `CSS.escape`,因此它们现在匹配而不是扔出"找不到匹配".
-   失败的解析器会抛出它自己命名ID的错误, 并带有解析器 `SyntaxError` 作为 `cause`,而不是光刻错误.
-   错误来自 `Serialize` 将原始错误带入 `cause`. 此前,它作为第二个论点被通过: `Error()` 并悄悄地放弃.
-   这个 `astro` 拓宽对等依赖 `^6` 改为 `>=4`,因此软件包安装在Astro 4、5和6上.

## 路线图

见 [TODO 跟踪器](https://todo.sr.ht/~ayoayco/astro-resume) 已规划的工作项目.

## 报告问题

要报告问题或要求特性,请开罚单 [GitHub 图像](https://github.com/ayo-run/astro-resume/issues),或发送纯文本电子邮件给 [~ayoayco/astro-resume@todo.sr.ht](mailto:~ayoayco/astro-resume@todo.sr.ht)

## 常见问题

### @ayco/astro-resume 是什么？

Astro 中的安全服务器对客户端数据

### 如何安装 @ayco/astro-resume？

在项目目录运行 npm install @ayco/astro-resume，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：astro（\>=4）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @ayco/astro-resume 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/ayco\_\_astro-resume 是否存在。

### @ayco/astro-resume 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @ayco/astro-resume 可以商用吗？

@ayco/astro-resume 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @ayco/astro-resume 的下载量有多少？

根据 npm 官方下载统计，@ayco/astro-resume 在 2026/10/08 – 2026/11/06 这 30 天内被下载 1,895 次，日均约 63 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @ayco/astro-resume 还在维护吗？

最新版本 1\.1\.1 发布于 2026/08/13（2 个月前）；至今共发布 40 个版本，其中过去 12 个月发布了 5 个；首次发布于 2023/07/16。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

