# @fanoutio/serve-grip 中文文档

规范地址：https://npmcn.com/package/%40fanoutio/serve-grip/

版本：4\.3\.0
npm 元数据更新时间：2026-11-07T20:16:43.600Z
中文译文更新时间：2026-11-14T09:57:28.913Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40fanoutio/serve-grip
原文对照：https://npmcn.com/package/%40fanoutio/serve-grip/?lang=original
项目主页：https://github.com/fanout/js-serve-grip#readme
源码仓库：https://github.com/fanout/js-serve-grip

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

- 包体积（解压后）：60.1 kB，57 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：3 个
- peer 依赖：hono ^4\.0\.0，@fastly/js-compute ^3\.0\.0 \|\| ^4\.0\.0
- 首次发布：2020-08-22T07:06:56.593Z
- 最新版本发布：2026-11-07T20:16:43.178Z
- 近 30 天下载量：23124（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：32（近 12 个月 3 个）

## 中文简介

GRIP 的连接风格中端软件

## 安装

```sh
npm install @fanoutio/serve-grip
```

也可以使用：`pnpm add @fanoutio/serve-grip`、`yarn add @fanoutio/serve-grip`、`bun add @fanoutio/serve-grip`

## README

## js-serve-grip (英语)

为 JavaScript 提供的 GRIP 库 `express` 财务报告和审定财务报表 `hono` 兼容的中间软件.

此库旨在协助创建后端服务器应用程序 使用 JavaScript 编写的 [加纳](https://pushpin.org/docs/protocols/grip/)。 。 。 . 该图书馆可通过以下框架使用:

-   [快递](https://expressjs.com/)
-   [浩诺](https://hono.dev/)
-   [下一个.js](https://nextjs.org/)
-   [连接](https://github.com/senchalabs/Connect)
-   [科亚](https://koajs.org/) \* 实验性支助

支持的GRIP服务器包括:

-   [推动](http://pushpin.org/)
-   [快速闪出](https://docs.fastly.com/products/fanout)

作者:大武之子 [库穆罗@ fastly.com](mailto:komuro@fastly.com)康斯坦丁·博卡里乌斯 [kon@ fanout.io (英语)](mailto:kon@fanout.io)

## V3 新建

### 中断更改

-   `ServeGripBase` 不再声明 `monkeyPatchResMethodsForWebSocket` 财务报告和审定财务报表 `monkeyPatchResMethodsForGripInstruct` 抽象的方法。 相反, 结尾处 `run` 方法,该 `onAfterSetup()` 方法被称为.

### 增强

-   现在添加支持 [浩诺](https://hono.dev/) 框架.

## 使用量

### 导言

[加纳](https://pushpin.org/docs/protocols/grip/) 是允许网络服务使用 代理实时将行为推向代理组件,使用HTTP和头.

`@fanoutio/serve-grip` 是一个服务器中间软件,它与 Express 和 何诺. 它会:

-   提供一个简单而直截了当的方法来配置这些框架与您的 GRIP 代理
-   描述 `Grip-Sig` 在任何检测是否通过 Grip 代理请求中的页眉
-   为您的路由处理器提供处理此类请求的工具,例如:
    -   访问当前请求是代理还是签名的信息
    -   您可以调用的方法向 GRIP 代理发布任何指令
-   提供进入 `Publisher` 对象,允许您的应用程序通过 gRIP出版社.

此外, `serve-grip` 也处理 [WebSocket- Over- HTTP 处理](https://pushpin.org/docs/protocols/websocket-over-http/) 这样 由 GRIP 代理管理的 WebSocket 连接可由您的路由处理器控制 .

### 安装

安装库.

```sh
npm install @fanoutio/serve-grip
```

#### 在快件/ 连接中安装

导入 `ServeGrip` 课程从 `@fanoutio/serve-grip/node` 将中间的软件立即释放 那先装好 你的路线.

示例

```javascript
import express from 'express';
import { ServeGrip } from '@fanoutio/serve-grip/node';

const app = express();

const serveGripMiddleware = new ServeGrip(/* config */);
app.use(serveGripMiddleware); 

app.use('/path', (res, req) => {

    if (req.grip.isProxied) {
        const gripInstruct = res.grip.startInstruct();
        gripInstruct.addChannel('test');
        gripInstruct.setHoldStream();
        res.end('[stream open]\n');
    }

});

app.listen(3000);
```

#### 在Hono安装

> \[注\] 强烈建议使用 [类型脚本](https://www.typescriptlang.org/) 和浩诺合作的时候.

导入 `serveGrip` 函数从 `@fanoutio/serve-grip/hono` 将中间的软件立即释放 那先装好 你的路线.

指定配置对象 `serveGrip` 可以在召回中完成。 这对这样的环境很有用 用于快速计算,其中在请求处理前可能无法进行配置.

此外,导入 `Env` 键入并当即时使用 `Hono`类型 检查 `c.var.grip` 上下文变量.

示例

```typescript
import { serve } from '@hono/node-server';
import { Hono } from 'hono';
import { serveGrip, type Env } from '@fanoutio/serve-grip/hono';

const app = new Hono<Env>();

const serveGripMiddleware = serveGrip(() => /* config */);
app.use(serveGripMiddleware);

app.use( '/path', async (c) => {

    if (c.var.grip.isProxied) {
        const gripInstruct = c.var.grip.startInstruct();
        gripInstruct.addChannel(CHANNEL_NAME);
        gripInstruct.setHoldStream();
        return c.text('[stream open]\n');
    }

});

serve({ fetch: app.fetch, port: 3000 }, (addr) => {
    console.log(`Example app listening on port ${addr.port}!`)
});
```

> \[注\] 以上的例子为Hono在Node.js上运行. 何诺可以使用 其他服务器平台也是如此。 关于修改应用程序使之适应 其他平台,见 [浩诺的向导](https://hono.dev/docs/getting-started/basic)。 。 。 .
> 
> 在后端应用程序运行时使用此库的实例 在“快速计算”上,检查以下示例应用程序:
> 
> -   [hono-compute-http (韩语)](https://npmcn.com/package/%40fanoutio/serve-grip/examples/hono-compute-http)
> -   [胡诺计算](https://npmcn.com/package/%40fanoutio/serve-grip/examples/hono-compute-ws)

#### 在Koa安装(实验)

导入 `ServeGrip` 课程从 `@fanoutio/serve-grip/node` 并立即进行。 Koa 中间软件可用 作为 `.koa` 对象上的属性。 在你的路线前安装它.

示例

```javascript
import Koa from 'koa';
import Router from '@koa/router';
import { ServeGrip } from '@fanoutio/serve-grip/node';

const app = new Koa();

const serveGripMiddleware = new ServeGrip(/* config */);
app.use(serveGripMiddleware.koa);

const router = new Router();

router.use( '/path', ctx => {

    if (ctx.req.grip.isProxied) {
        const gripInstruct = res.grip.startInstruct();
        gripInstruct.addChannel('test');
        gripInstruct.setHoldStream();
        ctx.body = '[stream open]\n';
    }

});

app.use(router.routes())
    .use(router.allowedMethods());

app.listen(3000);
```

#### 在下一个.js安装

您可以使用此库将 GRIP 功能添加到您的 [Next.js API 路由](https://nextjs.org/docs/api-routes/introduction)。 。 。 .

导入 `ServeGrip` 课程从 `@fanoutio/serve-grip/node` 将中间的软件立即放入 您的处理器在应用程序逻辑之前, 通过调用 async 函数 `serveGripMiddleware.run()`。 。 。 .

示例 `/lib/grip.js`数字 :

```javascript
import { ServeGrip } from '@fanoutio/serve-grip/node';
export const serveGripMiddleware = new ServeGrip(/* config */);
```

`/pages/api/path.js`数字 :

```javascript
import { serveGripMiddleware } from '/lib/grip';

export default async(req, res) => {
    // Run the middleware
    if (!(await serveGripMiddleware.run(req, res))) {
        // If serveGripMiddleware.run() has returned false, it means the middleware has already
        // sent and ended the response, usually due to an error.  
        return;
    }

    if (req.grip.isProxied) {
        const gripInstruct = res.grip.startInstruct();
        gripInstruct.addChannel('test');
        gripInstruct.setHoldStream();
        res.end('[stream open]\n');
    }

}
```

> \[注\] 在 Next.js 中,您必须特别从每个应用的 API 路由中调用中间软件 . 这是因为在 Next.js 中,您的 API 路由通常会在无服务器的平台上运行, 对象 每次请求后都会被回收。 建议您构建一个单通实例 在共享位置的中间软件,并从您的 API 路由中引用 .

### 配置

`@fanoutio/serve-grip/node` 导出一个命名的类构造器 `ServeGrip`此构造器需要 用于配置实例的配置对象, 如要使用的 GRIP 代理 用于发布或收到的请求是否需要GRIP代理.

以下是GRIP代理作为实例时的配置实例: 在本地主机上驱动运行 :

```javascript
import { ServeGrip } from '@fanoutio/serve-grip/node';
const serveGripMiddleware = new ServeGrip({
    grip: {
        control_uri: 'https://localhost:5561/',   // Control URI for Pushpin publisher
        control_iss: '<issuer>',                  // (opt.) iss needed for publishing, if required by Pushpin
        key: '<publish-key>',                     // (opt.) key needed for publishing, if required by Pushpin
    },
    isGripProxyRequired: true,
});
```

以下为GRIP代理快速Fanout时的配置示例:

```javascript
import { ServeGrip } from '@fanoutio/serve-grip/node';
const serveGripMiddleware = new ServeGrip({
    grip: {
        control_uri: 'https://api.fastly.com/service/<service-id>/',   // Control URI
        key: '<fastly-api-token>',             // Authorization key for publishing (Fastly API Token)
        verify_iss: 'fastly:<service-id>',     // Fastly issuer used for validating Grip-Sig
        verify_key: '<verify-key>',            // Fastly public key used for validating Grip-Sig
    },
    isGripProxyRequired: true,
});
```

配置通常使用 `GRIP_URL` (如有需要, `GRIP_VERIFY_KEY`),允许使用简单的字符串进行配置。 这允许从环境变量进行配置:

```
GRIP_URL="https://api.fastly.com/service/<service-id>/?verify-iss=fastly:<service-id>&key=<fastly-api-token>"
GRIP_VERIFY_KEY="base64:LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFQ0tvNUExZWJ5RmNubVZWOFNFNU9uKzhHODFKeQpCalN2Y3J4NFZMZXRXQ2p1REFtcHBUbzN4TS96ejc2M0NPVENnSGZwLzZsUGRDeVlqanFjK0dNN3N3PT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t"
```

```javascript
import { ServeGrip } from '@fanoutio/serve-grip/node';

const serveGripMiddleware = new ServeGrip({
    grip: process.env.GRIP_URL,
    gripVerifyKey: process.env.GRIP_VERIFY_KEY,
    isGripProxyRequired: true,
});
```

> \[注\] 当和浩诺一起使用时, `@fanoutio/serve-grip/hono` 导出一个名为函数的函数 `serveGrip` 而不是一个建筑师. 此函数将对象与参数相同 `ServeGrip` 或承诺 解决此对象。 也可以使用回调来称呼它,以返回这样的对象或承诺. 这对快速计算等环境有用, 运行时配置可能要到 请求处理.
> 
> 示例
> 
> ```typescript
> import { serveGrip } from '@fanoutio/serve-grip/hono';
> 
> const serveGripMiddleware = serveGrip(async () => {
>     const gripUrl = await loadGripUrl();
>     return {
>         grip: gripUrl,
>     };
> });
> ```

可用的选项 :

| 密钥 | 数值 |
| --- | --- |
| `grip` | 用于发布信件的 GRIP 代理定义, 或预配置的 Publisher 对象 `@fanoutio/grip`详情见下文. |
| `gripVerifyKey` | (可选)可以用来指定 `verify-key` gRIP配置组件.  
只有在 -- --  
\* 联合国 `grip` 作为字符串、配置对象或配置对象的阵列提供  
\* 联合国 `grip` 尚未包含 `verify_key` 数值. |
| `gripProxyRequired` | (可选)布尔值代表是否所有收到的请求都要求将其调用到GRIP代理后. 如果这是真的,并且没有检测到 GRIP 代理,那么 `501 Not Implemented` 将发布错误 。 默认为 `false`。 。 。 . |
| `prefix` | (可选) 将预设为被发布频道名称的字符串 。 这可用于命名间隔. 默认为 `''`。 。 。 . |

在多数情况下,您的应用程序会构造此类的单通实例并用作 中间的软件.

这个 `grip` 参数可以是下列任何一种:

1.  以下字段为对象:
    
    | 外地 | 说明 |
    | --- | --- |
    | `control_uri` | GRIP客户端的控制URI. |
    | `control_iss` | (可选)控制国际空间站,如果GRIP客户要求. |
    | `key` | (可选)字符串或 Uint8Array 。 如果GRIP客户端需要,用于控制国际空间站的密钥. |
    | `verify_iss` | (可选) 用于验证GRIP签名的空间站. |
    | `verify_key` | (可选)字符串或 Uint8Array 。 用于验证 GRIP 签名的密钥 . |
    
2.  此类对象的阵列 .
    
3.  A GRIP URI,是将上方编码为单字符串的字符串.
    
4.  (高级)A `Publisher` 对象,从 `@fanoutio/grip`。 。 。 .
    

### 处理路径

在中间软件运行后, 您的处理器将接收 Grip 上下文 `grip` 联 合 国 `req` 财务报告和审定财务报表 `res` 对象或在Hono上 上下文 `c`) (中文(简体) ). 这些设施提供下列服务:

| 特快,可亚等. | 浩诺 | 说明 |
| --- | --- | --- |
| `req.grip.isProxied` | `c.var.grip.isProxied` | 一个布尔值表示当前请求是否通过 GRIP 代理调用 . |
| `req.grip.isSigned` | `c.var.grip.isSigned` | 一个布尔值, 表示当前请求是否是一个通过 GRIP 代理调用的签名请求 . |
| `req.grip.wsContext` | `c.var.grip.wsContext` | 如果当前请求是通过WebSocket-Over-HTTP提出的,则 `WebSocketContext` 当前请求的对象。 见 `@fanoutio/grip` 详细情况 `WebSocketContext`。 。 。 . |
| `res.grip.startInstruct()` | `c.var.grip.startInstruct()` | 返回实例 `GripInstruct`,可用于向GRIP代理发布指令以持有连接. 见 `@fanoutio/grip` 详细情况 `GripInstruct`。 。 。 . |

要发布信件,请获取 `Publisher`。使用它发布消息,使用中间软件初始化时指定的端点和前缀.

| 特快,可亚等. | 浩诺 | 说明 |
| --- | --- | --- |
| `serveGripMiddleware.getPublisher()` | `c.var.grip.getPublisher()` | 返回实例 `Publisher`,它可用于使用提供的前缀向提供的出版端点发布消息。 见 `@fanoutio/grip` 详细情况 `Publisher`。 。 。 . |

### 实例

该寄存器包含一些实例,以说明使用 `serve-grip` 在连接/快递中 和下一个.js,可在 `examples` 目录。 欲了解每个例子的详细情况,请 读取 `README.md` 在相应的目录中的文件.

### 高级

#### 快速计算

[快速计算](https://www.fastly.com/documentation/guides/compute/getting-started-with-compute/) 是高级 运行代码的边缘计算平台(被编译为WebAssembly)在快取的全球边缘网络上.

当使用快速计算时,单个应用程序可以同时使用 **启动 GRIP 移交** 财务报告和审定财务报表 **进程代理GRIP 请求** 将应用程序本身配置为后端。 在这个设定中,应用程序运行 _两次_ 按请求:

-   一次作为 **外部计算应用程序**,激活 GRIP 代理服务器
-   再次作为 **内部代理应用程序**,通过GRIP代理引用.

为了支持这种模式, `@fanoutio/serve-grip/hono` 提供了额外的Hono中间软件, **`fanoutSelfHandoffMiddleware`**,它会在快速计算 JavaScript 下运行时自动包含 SDK(通过 [`fastly` 有条件的运行时间密钥](https://runtime-keys.proposal.wintercg.org/#fastly)) (中文(简体) ).

```ts
import { fanoutSelfHandoffMiddleware } from '@fanoutio/serve-grip/hono';

app.get('/api/*', fanoutSelfHandoffMiddleware('self'));
```

此中间软件检查应用程序是否在外部计算上下文中运行, 或是内在的代理上下文 :

-   在那个 **外部** 上下文,它执行 Fanout 交接回 `'self'`,必须定义为您的后端 快速服务 指向自己.
-   在那个 **内** 上下文中,它允许继续请求.

> \[注\] 此寄存器中的例子以 [快速 Fanout 本地测试](https://www.fastly.com/documentation/guides/concepts/real-time-messaging/fanout/#run-the-service-locally)数字 :
> 
> -   [hono-compute-http (韩语)](https://npmcn.com/package/%40fanoutio/serve-grip/examples/hono-compute-http)
> -   [胡诺计算](https://npmcn.com/package/%40fanoutio/serve-grip/examples/hono-compute-ws)

在向您的快速账户部署时,确保:

1.  **Fanout 已启用** 为你服务,和
2.  A 类 **指向自己的后端** 已配置.

详情见 [部署到快递处](https://www.fastly.com/documentation/guides/concepts/real-time-messaging/fanout/#deploy-to-a-fastly-service) 在快速文档中.

## 许可证

(C)2015,2020 Fanout, Inc.  
(C)2025快通股份有限公司. 根据麻省理工学院的许可,详情见文件LICENSE.md.

## 常见问题

### @fanoutio/serve-grip 是什么？

GRIP 的连接风格中端软件

### 如何安装 @fanoutio/serve-grip？

在项目目录运行 npm install @fanoutio/serve-grip，或使用 pnpm add / yarn add / bun add。

### @fanoutio/serve-grip 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @fanoutio/serve-grip 支持 ESM 还是 CommonJS？

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

### @fanoutio/serve-grip 可以商用吗？

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

### @fanoutio/serve-grip 的下载量有多少？

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

### @fanoutio/serve-grip 还在维护吗？

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

