# @cloudflare/containers 中文文档

规范地址：https://npmcn.com/package/%40cloudflare/containers/

版本：0\.3\.7
npm 元数据更新时间：2026-06-29T18:54:29.354Z
中文译文更新时间：2026-11-10T02:55:31.251Z
软件包许可：MIT OR Apache-2\.0

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

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

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

- 包体积（解压后）：176 kB，17 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2025-06-02T20:55:46.616Z
- 最新版本发布：2026-06-04T21:01:01.406Z
- 近 30 天下载量：8830233（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：46（近 12 个月 16 个）

## 中文简介

集装箱辅助持久物体的辅助人员类别

## 安装

```sh
npm install @cloudflare/containers
```

也可以使用：`pnpm add @cloudflare/containers`、`yarn add @cloudflare/containers`、`bun add @cloudflare/containers`

## README

# 集装箱

在Cloudflare工人上与集装箱互动的班级.

## 特征

-   HTTP 请求代理和 WebSocket 转发
-   在HTTPS支助下,由主机或全覆盖处理器拦截外部请求
-   主机允许/ 拒绝列表与 glob 模式匹配
-   简单的集装箱生命周期管理(起动和停放集装箱)
-   集装箱生命周期事件的事件钩子(启动、停止、错误)
-   根据请求更新的可配置睡眠超时
-   装入平衡公用事业

## 安装

```bash
npm install @cloudflare/containers
```

## 基本示例

```typescript
import { Container, getContainer, getRandom } from '@cloudflare/containers';

export class MyContainer extends Container {
  // Configure default port for the container
  defaultPort = 8080;
  // After 1 minute of no new activity, shutdown the container
  sleepAfter = '1m';
}

export default {
  async fetch(request, env) {
    const pathname = new URL(request.url).pathname;

    // If you want to route requests to a specific container,
    // pass a unique container identifier to .get()

    if (pathname.startsWith('/specific/')) {
      // In this case, each unique pathname will spawn a new container
      const container = env.MY_CONTAINER.getByName(pathname);
      return await container.fetch(request);
    }

    // Note: this is a temporary method until built-in autoscaling and load balancing are added.
    // If you want to route to one of many containers (in this case 5), use the getRandom helper.
    // This load balances incoming requests across these container instances.
    let container = await getRandom(env.MY_CONTAINER, 5);
    return await container.fetch(request);
  },
};
```

## API 参考

### `Container` 类

这个 `Container` class 扩展了容器阻塞的持久对象,以提供额外的容器特定功能.

#### 属性

-   `defaultPort?`
    
    与容器通信时使用的可选默认端口 。 如果未设置此选项, 或者您想要瞄准您的容器上的特定端口, 您可以指定端口 `fetch(switchPort(req, 8080))` 或者说 `containerFetch(req, 8080)`。 。 。 .
    
-   `requiredPorts?`
    
    集装箱启动时应当检查可用的端口序列。 用于 `startAndWaitForPorts` 在未提供特定端口的情况下.
    
-   `sleepAfter`
    
    容器在无活性情况下能活多久(格式:数为秒,或"5m","30s","1h"等字符串).
    
    默认为"10m",指集装箱级持久对象在10分钟内没有收到请求后会关闭容器.
    

以下属性用于设定启动容器时的默认值, 但可以通过将数值传递到 `startAndWaitForPorts()` 或者说 `start()`。 。 。 .

-   `env?: Record<string, string>`
    
    启动时要传递到容器的环境变量 .
    
-   `entrypoint?: string[]`
    
    指定一个切入点来覆盖图像默认值.
    
-   `enableInternet: boolean`
    
    是否允许容器的互联网访问 .
    
    默认为 `true`。 。 。 .
    
-   `interceptHttps: boolean`
    
    何时 `true`,出站的HTTPS流量也通过与HTTP相同的处理链被拦截. 容器必须信任 Cloudflare 提供的 CA 证书 `/etc/cloudflare/certs/cloudflare-containers-ca.crt`。见 [Egress 文件](https://npmcn.com/package/%40cloudflare/containers/docs/egress.md#intercepthttps) 每次分发的设置指令.
    
    默认为 `false`。 。 。 .
    
-   `allowedHosts: string[]`
    
    主机名模式的白名单 。 当非空时,只有匹配的主机才能通过允许检查进行;其他的都被屏蔽了(HTTP 520). 支持简单的模糊模式 `*` 匹配任意字符序列(例如. `'*.example.com'`) (中文(简体) ).
    
-   `deniedHosts: string[]`
    
    主机名模式块列表 。 匹配主机无条件被屏蔽(HTTP 520),压倒了处理器链中其他所有,包括每个主机处理器. 支持与 `allowedHosts`。 。 。 .
    
-   `pingEndpoint: string`
    
    指定容器类的端点,以检查是否启动基本实例. 这不需要由大多数人来设定, 只有在你喜欢集装箱主管时才使用 当容器启动时,它会击中容器的另一端. 看着 `pingEndpoint` 可同时包括主机名和路径。 你们可以 设定 `container/health`,含义 `"container"` 将是沿 `Host` 页眉,以及 `"/health"` 路径.
    
    默认为 `ping`。 。 。 .
    

#### 方法

##### 生命周期钩

当容器状态过渡时,这些生命周期方法会自动被称作. 取代这些方法使用这些钩子.

见 [此示例](https://npmcn.com/package/%40cloudflare/containers/#readme-http-example-with-lifecycle-hooks)。 。 。 .

-   `onStart()`
    
    当容器成功启动时调用 .
    
    -   当状态从 `stopped` - > (中文) `running`, (中文(简体) ), `running` - > (中文) `healthy`
-   `onStop()`
    
    集装箱关机时打过电话.
    
-   `onError(error)`
    
    当容器遇到错误时调用,并默认日志并丢出错误.
    
-   `onActivityExpired()`
    
    活动到期时调用. 在上次活动之后, 容器将继续运行一段时间 - 这个时间长度由 `sleepAfter`。 。 。 . 默认情况下,它会用 `SIGTERM`,但你可以推翻这个行为, 就像其他生命周期钩。 然而,如果不在这里停止容器,活性追踪器会被更新,这个生命周期钩在计时器再过期时再次被叫来.
    

##### 集装箱方法

-   `fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>`
    
    向容器转发 HTTP 请求 .
    
    如果您想瞄准容器上的特定端口,而不是默认端口,应当使用 `switchPort` 像这样:
    
    ```typescript
    const container = env.MY_CONTAINER.getByName('id');
    await container.fetch(switchPort(request, 8080));
    ```
    
    请确保您提供带有开关的端口或指定带有开关的端口 `defaultPort` 属性.
    
    您必须使用 `fetch` 而不是说 `containerFetch` 如果您想要转发 websockets .
    
    请注意,当您调用任何获取函数时,活动会自动被更新(在上次活动后开始后睡眠),如果尚未运行,容器会启动 .
    
-   `containerFetch(...)`
    
    说明: `containerFetch` 不与 websockets 工作.
    
    向容器发送 HTTP 请求 。 支持两个标准获取 API 签名 :
    
    -   `containerFetch(request, port?)`: 带有请求对象的传统签名
    -   `containerFetch(url, init?, port?)`: 有 URL 字符串/对象和 RequestInit 选项的标准获取式签名
-   `startAndWaitForPorts(args: StartAndWaitForPortsOptions): Promise<void>`
    
    启动容器,然后等待指定端口做好准备。 优先事项 `ports` 传到函数,然后 `requiredPorts` 如果设置,那么 `defaultPort`。 。 。 .
    
    ```typescript
    interface StartAndWaitForPortsOptions {
      startOptions?: {
        /** Environment variables to pass to the container */
        envVars?: Record<string, string>;
        /** Custom entrypoint to override container default */
        entrypoint?: string[];
        /** Whether to enable internet access for the container */
        enableInternet?: boolean;
      };
      /** Ports to check */
      ports?: number | number[];
      cancellationOptions?: {
        /** Abort signal to cancel start and port checking */
        abort?: AbortSignal;
        /** Max time to wait for container to start, in milliseconds */
        instanceGetTimeoutMS?: number;
        /** Max time to wait for ports to be ready, in milliseconds */
        portReadyTimeoutMS?: number;
        /** Polling interval for checking container has started or ports are ready, in milliseconds */
        waitInterval?: number;
      };
    }
    ```
    
-   `start(startOptions?: ContainerStartConfigOptions, waitOptions?: WaitOptions)`
    
    启动集装箱,不等待任何港口做好准备.
    
    你最好用这个代替 `startAndWaitForPorts` 如果你想的话:
    
    -   在端口可用之前不屏蔽启动容器
    -   初始化不暴露端口的容器
    -   单独进行自定义端口可用性检查
    
    选项 :
    
    ```typescript
    interface ContainerStartConfigOptions {
      /** Environment variables to pass to the container */
      envVars?: Record<string, string>;
      /** Custom entrypoint to override container default */
      entrypoint?: string[];
      /** Whether to enable internet access for the container */
      enableInternet?: boolean;
    }
    
    interface WaitOptions {
      /** The port number to check for readiness */
      portToCheck: number;
      /** Optional AbortSignal, use this to abort waiting for ports */
      signal?: AbortSignal;
      /** Number of attempts to wait for port to be ready */
      retries?: number;
      /** Time to wait in between polling port for readiness, in milliseconds */
      waitInterval?: number;
    }
    ```
    
-   `stop(signal = SIGTERM): Promise<void>`
    
    向容器发送指定的信号。 触发器 `onStop`。 。 。 .
    
-   `destroy(): Promise<void>`
    
    强制销毁容器(发送) `SIGKILL`) (中文(简体) ). 触发器 `onStop`。 。 。 .
    
-   `getState(): Promise<State>`
    
    获取当前容器状态 .
    
    ```typescript
    type State = {
      lastChange: number;
    } & (
      | {
          // 'running' means that the container is trying to start and is transitioning to a healthy status.
          //           onStop might be triggered if there is an exit code, and it will transition to 'stopped'.
          status: 'running' | 'stopping' | 'stopped' | 'healthy';
        }
      | {
          status: 'stopped_with_code';
          exitCode?: number;
        }
    );
    ```
    
-   `renewActivityTimeout()`
    
    手动更新容器活度超时(延长容器寿命).
    

##### 外出拦截

当您想要控制容器所能达到的时使用出站拦截,或者通过工人代码代理出站请求.

-   `setOutboundByHost(host: string, method: string): Promise<void>`
    
    将特定主机名从 `static outboundHandlers`。 。 。 .
    
-   `setOutboundByHosts(handlers: Record<string, string>): Promise<void>`
    
    立即替换所有运行时主机特定覆盖 .
    
-   `removeOutboundByHost(host: string): Promise<void>`
    
    删除运行时主机特定覆盖 .
    
-   `setOutboundHandler(method: string): Promise<void>`
    
    设置所有外出处理器到命名处理器 `static outboundHandlers`。 。 。 .
    
-   `setAllowedHosts(hosts: string[]): Promise<void>`
    
    在运行时替换允许的主机列表 .
    
-   `setDeniedHosts(hosts: string[]): Promise<void>`
    
    运行时替换已拒绝的主机列表 .
    
-   `allowHost(hostname: string): Promise<void>`
    
    在允许列表中添加单个主机.
    
-   `denyHost(hostname: string): Promise<void>`
    
    在拒绝的列表中添加单个主机.
    
-   `removeAllowedHost(hostname: string): Promise<void>`
    
    从允许的列表中删除主机.
    
-   `removeDeniedHost(hostname: string): Promise<void>`
    
    从拒绝的列表中删除主机.
    

要配置类本身的截取:

-   `static outbound = (req, env, ctx) => Response`
    
    接通所有出入境请求的人.
    
-   `static outboundByHost = { [host]: handler }`
    
    精确主机名匹配的每个主机处理器, 如 `google.com` 或者一个IP地址.
    
-   `static outboundHandlers = { [name]: handler }`
    
    在运行时可选择的指定处理器 `setOutboundHandler` 财务报告和审定财务报表 `setOutboundByHost`。 。 。 .
    

处理顺序( 第一局胜出) :

1.  **拒绝主机** - 如果主机名称匹配任何 `deniedHosts` 模式,请求被屏蔽(HTTP 520). 超越一切诸相.
2.  **允许的主机门** 如果 `allowedHosts` 是非空的,主机名不匹配,请求被屏蔽(HTTP 520). 何时 `allowedHosts` 此步骤已跳过.
3.  **每个东道主处理器运行时间** —— 说 `setOutboundByHost()` 覆盖
4.  **静态/ 主机处理器** —— 说 `outboundByHost`
5.  **运行时间控制器** —— 说 `setOutboundHandler()` 覆盖
6.  **静态控制器** —— 说 `outbound`
7.  **允许主机互联网回落** - 如果主机名匹配 `allowedHosts` 但上面没有处理者处理过,请求被传送到互联网(即使 `enableInternet` 实值 `false`) (中文(简体) ).
8.  **`enableInternet` 倒计时** 如果 `true`请求会传到互联网上.
9.  **默认拒绝** ——请求被封(HTTP 520).

-   `schedule<T = string>(when: Date | number, callback: string, payload?: T): Promise<Schedule<T>>`
    
    选项 :
    
    -   `when`: 何时执行任务(日期对象或秒数延迟)
    -   `callback`: 要调用为字符串的函数名称
    -   `payload`: 数据传递给召回
    
    而不是使用默认的提醒处理器, 使用 `schedule()` 换句话说 默认的报警处理器负责更新容器活性并保持耐用物体活性. 您可以覆盖 `alarm()`由于其功能目前对于管理集装箱生命周期至关重要,我们建议调用 `schedule` 来安排任务.
    

### 工具函数

-   `getRandom(binding, instances?: number)`
    
    在 N 实例中获取一个随机的容器实例 。 这对于负载平衡有用. 返回容器的根. 见 [实例](https://npmcn.com/package/%40cloudflare/containers/#readme-using-load-balancing)。 。 。 .
    
-   `getContainer(binding, name?: string)` 帮助获得特定容器实例根茎.
    
    譬如说. `const container = getContainer(env.CONTAINER, "unique-id")`
    
    如果没有提供名称,则使用"参考-singleton-container".
    

## 实例

### HTTP 有生命周期钩的示例

```typescript
import { Container } from '@cloudflare/containers';

export class MyContainer extends Container {
  // Configure default port for the container
  defaultPort = 8080;

  // Set how long the container should stay active without requests
  // Supported formats: "10m" (minutes), "30s" (seconds), "1h" (hours), or a number (seconds)
  sleepAfter = '10m';

  // Lifecycle method called when container starts
  override onStart(): void {
    console.log('Container started!');
  }

  // Lifecycle method called when container shuts down
  override onStop(): void {
    console.log('Container stopped!');
    // you can also call startAndWaitForPorts() again
    //   this.startAndWaitForPorts();
  }

  // Lifecycle method called on errors
  override onError(error: unknown): any {
    console.error('Container error:', error);
    throw error;
  }

  // Lifecycle method when the container class considers the activity to be expired
  override onActivityExpired() {
    console.log('Container activity expired');
    await this.destroy();
  }

  // Custom method that will extend the container's lifetime
  async performBackgroundTask(): Promise<void> {
    // Do some work...

    // Renew the container's activity timeout
    await this.renewActivityTimeout();
    console.log('Container activity timeout extended');
  }

  // Additional methods can be implemented as needed
}
```

### WebSocket 支持

容器类自动支持代理WebSocket连接您的容器。 WebSocket连接是双向的代理,消息以双向传输. 当WebSocket消息发送或收到时,容器也会自动更新活动超时.

```typescript
// Connect to a WebSocket on port 9000
const response = await container.fetch(switchPort(request, 9000));
```

备注 Websockets 不支持 `containerFetch`。 。 。 .

### 容器配置示例

您可以通过设置环境变量、入站点和网络访问的实例属性来配置容器起始的默认值:

```typescript
import { Container } from '@cloudflare/containers';

export class ConfiguredContainer extends Container {
  // Default port for the container
  defaultPort = 9000;

  // Set the timeout for sleeping the container after inactivity
  sleepAfter = '2h';

  // Environment variables to pass to the container
  envVars = {
    NODE_ENV: 'production',
    LOG_LEVEL: 'info',
    APP_PORT: '9000',
  };

  // Custom entrypoint to run in the container
  entrypoint = ['node', 'server.js', '--config', 'production.json'];

  // Enable internet access for the container
  enableInternet = true;

  // These configuration properties will be used automatically
  // when the container starts
}
```

您也可以在每封邮件中按 `start` 或者说 `startAndWaitForPorts`

### 外出拦截

这样你就可以拦截到 集装箱对外界的要求.

您必须导出 `ContainerProxy` 从您的工人入境点截取出入境工作:

```typescript
export { ContainerProxy } from '@cloudflare/containers';
```

```typescript
import { Container, OutboundHandlerContext } from '@cloudflare/containers';

export class MyContainer extends Container {
  defaultPort = 8080;
  enableInternet = false;
  interceptHttps = true; // also intercept HTTPS outbound traffic

  // Only allow these hosts through the egress chain
  allowedHosts = ['google.com', 'github.com', 'api.stripe.com'];
  // Block these hosts unconditionally, even if they appear in allowedHosts
  deniedHosts = ['evil.com', '*.malware.net'];

  static outboundByHost = {
    'google.com': (_req: Request, _env: unknown, ctx: OutboundHandlerContext) => {
      return new Response('hi ' + ctx.containerId + ' i am google');
    },
  };

  static outboundHandlers = {
    async github(_req: Request, _env: unknown, _ctx: OutboundHandlerContext) {
      return new Response('i am github');
    },
  };

  static outbound = (req: Request) => {
    return new Response(`Hi ${req.url}, I can't handle you`);
  };

  async routeGithubThroughHandler(): Promise<void> {
    await this.setOutboundByHost('github.com', 'github');
  }

  async makeEverythingUseGithubHandler(): Promise<void> {
    await this.setOutboundHandler('github');
  }
}
```

使用 `outboundByHost` 对于固定的东道主规则, `outbound` 对于默认的包罗万象,和 `outboundHandlers` 用于运行时您想要打开的重用名处理器。 使用 `allowedHosts` 财务报告和审定财务报表 `deniedHosts` 用于基于 glob 主机过滤(例如). `'*.example.com'`) (中文(简体) ). 见 [完整胶卷文件](https://npmcn.com/package/%40cloudflare/containers/docs/egress.md) 用于HTTPS拦截的详细拦截策略和CA证书设置.

### 多个端口和自定义运行

您可以创建一个不使用默认端口的容器, 转而根据请求路径或其他因素将流量引导到不同的端口 :

```typescript
import { Container } from '@cloudflare/containers';

export class MultiPortContainer extends Container {
  // No defaultPort defined - we'll handle port specification manually

  constructor(ctx: any, env: any) {
    super(ctx, env);
  }

  /**
   * Process an incoming request and route to different ports based on path
   */
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    try {
      if (url.pathname.startsWith('/api')) {
        // API server runs on port 3000
        return await this.containerFetch(request, 3000);
      } else if (url.pathname.startsWith('/admin')) {
        // Admin interface runs on port 8080
        return await this.containerFetch(request, 8080);
      } else {
        // Public website runs on port 80
        return await this.containerFetch(request, 80);
      }
    } catch (error) {
      return new Response(`Error: ${error instanceof Error ? error.message : String(error)}`, {
        status: 500,
      });
    }
  }
}
```

### 使用标准获取 API 语法

您可以使用标准获取 API 语法的 ContexFetch 方法 :

```typescript
import { Container } from '@cloudflare/containers';

export class FetchStyleContainer extends Container {
  defaultPort = 8080;

  async customHandler(): Promise<Response> {
    try {
      // Using the new fetch-style syntax
      const response = await this.containerFetch('/api/data', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ query: 'example' }),
      });

      // You can also specify a port with this syntax
      const adminResponse = await this.containerFetch(
        'https://example.com/admin',
        { method: 'GET' },
        3000 // port
      );

      return response;
    } catch (error) {
      return new Response(`Error: ${error instanceof Error ? error.message : String(error)}`, {
        status: 500,
      });
    }
  }
}
```

### 集装箱停放管理

集装箱类别包括一个自动闲置的超时功能,在一段时间后会关闭集装箱. 这有助于在不使用容器时节省资源.

```typescript
import { Container } from '@cloudflare/containers';

export class TimeoutContainer extends Container {
  // Configure default port for the container
  defaultPort = 8080;

  // Set timeout to 30 minutes of inactivity
  sleepAfter = '30m'; // Supports "30s", "5m", "1h" formats, or a number in seconds

  // Custom method that will extend the container's lifetime
  async performBackgroundTask(data: any): Promise<void> {
    console.log('Performing background task...');

    // Manually renew the activity timeout, even though
    // you have not made a request to the container
    await this.renewActivityTimeout();

    console.log('Container activity timeout renewed');
  }

  // Activity timeout is automatically renewed on fetch requests
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    // Example endpoint to trigger background task
    if (url.pathname === '/task') {
      await this.performBackgroundTask();

      return new Response(
        JSON.stringify({
          success: true,
          message: 'Background task executed',
          nextStop: `Container will shut down after ${this.sleepAfter} of inactivity`,
        }),
        { headers: { 'Content-Type': 'application/json' } }
      );
    }

    // For all other requests, forward to the container
    // This will automatically renew the activity timeout
    return this.containerFetch(request);
  }
}
```

### 使用负载平衡

这个软件包包括 `getRandom` 向 N 例请求的帮助. 今后,将通过资源意识负荷平衡自动处理 当自动缩放设定为真实时, 但它尚未执行 .

```typescript
import { Container, getContainer, getRandom } from '@cloudflare/containers';

export class MyContainer extends Container {
  defaultPort = 8080;
}

export default {
  async fetch(request: Request, env: any) {
    const url = new URL(request.url);

    // Example: Load balance across 5 container instances
    if (url.pathname === '/api') {
      const containerInstance = await getRandom(env.MY_CONTAINER, 5);
      return containerInstance.fetch(request);
    }

    // Example: Direct request to a specific container
    if (url.pathname.startsWith('/specific/')) {
      const id = url.pathname.split('/')[2] || 'default';
      const containerInstance = getContainer(env.MY_CONTAINER, id);
      return containerInstance.fetch(request);
    }

    return new Response('Not found', { status: 404 });
  },
};
```

## 常见问题

### @cloudflare/containers 是什么？

集装箱辅助持久物体的辅助人员类别

### 如何安装 @cloudflare/containers？

在项目目录运行 npm install @cloudflare/containers，或使用 pnpm add / yarn add / bun add。

### @cloudflare/containers 支持 TypeScript 吗？

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

### @cloudflare/containers 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @cloudflare/containers 可以商用吗？

@cloudflare/containers 使用 MIT OR Apache-2\.0 许可。可在 MIT、Apache-2\.0 中任选其一遵守。选择 MIT 时，宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @cloudflare/containers 的下载量有多少？

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

### @cloudflare/containers 还在维护吗？

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

