# 数据传输

> Source: https://strapi.nodejs.cn/cms/features/data-management/transfer

🌐 Data transfer

`strapi transfer` 命令在两个具有相同模式的 Strapi 实例之间传输数据，使用传输令牌进行授权和身份验证，从而传输内容、文件和配置。

🌐 The `strapi transfer` command streams data between two Strapi instances with identical schemas, transferring content, files, and configuration using transfer tokens for authorization and authentication.

`strapi transfer` 命令是 [数据管理功能](/cms/features/data-management) 的一部分，用于将数据从一个 Strapi 实例流式传输到另一个 Strapi 实例。`transfer` 命令使用严格的模式匹配，这意味着你的两个 Strapi 实例需要完全相同，唯一的区别是包含的数据。默认的 `transfer` 命令会传输你的内容（实体和关系）、文件（资源）、项目配置以及模式。该命令允许你传输数据：

🌐 The `strapi transfer` command is part of the [Data Management feature](/cms/features/data-management) and streams your data from one Strapi instance to another Strapi instance. The `transfer` command uses strict schema matching, meaning your two Strapi instances need to be exact copies of each other except for the contained data. The default `transfer` command transfers your content (entities and relations), files (assets), project configuration, and schemas. The command allows you to transfer data:

- 从本地 Strapi 实例到远程 Strapi 实例
- 从远程 Strapi 实例到本地 Strapi 实例

以下文档详细说明了可用于自定义数据传输的选项。传输命令及所有可用选项均通过 [Strapi CLI](/cms/cli#strapi-transfer) 运行。

🌐 The following documentation details the available options to customize your data transfer. The transfer command and all of the available options are run using the [Strapi CLI](/cms/cli#strapi-transfer).

:::caution

* 如果你在目标实例中使用 SQLite 数据库，当 `transfer` 操作正在运行时，其他数据库连接将被阻塞。
* 管理员用户和 API 令牌不会转移。
* 如果你的项目使用 websockets 或 Socket.io，这个命令会失败。请参见 [故障排除](#troubleshooting)。

:::

CLI 命令包含以下参数：

🌐 The CLI command consists of the following arguments:

| 选项 | 描述 |
| --- | --- |
| `--to` | 目标 Strapi 实例上 `/admin` 端点的完整 URL<br />（例如 `--to https://my-beautiful-strapi-website/admin`） |
| `--to-token` | 从 Strapi 目标实例转移令牌。 |
| `--from` | 要从中提取数据的远程 Strapi 实例的 `/admin` 端点的完整 URL（例如，`--from https://my-beautiful-strapi-website/admin`） |
| `--from-token` | 从 Strapi 源实例转移令牌。 |
| `--force` | 自动对所有提示回答“是”，包括可能具有破坏性的请求，并以非交互方式运行。 |
| `--exclude` | 使用逗号分隔的数据类型来排除数据。可用的数据类型有：`content`、`files`、`config` 和 `media-library`（排除上传的二进制文件和上传的内容类型记录）。 |
| `--only` | 仅包含这些数据。可用的类型有：`content`、`files` 和 `config`。 |
| `--exclude-content-types` | 要排除的内容类型 UID 的逗号分隔列表。任何涉及被排除类型的实体记录和关联链接都会被跳过。 |
| `--only-content-types` | 要包含的内容类型 UID 的逗号分隔列表。只会传输列出的类型的实体记录和关联链接。 |
| `--throttle` | 在每个传输的实体之间注入人工延迟的时间（毫秒）。 |
| `--no-checksums` | 禁用资源的端到端 SHA-256 校验和验证。当源实例和目标实例都支持校验和验证时，默认启用校验和验证。 |
| `--verbose` | 启用详细日志。 |

必须提供 `--to` 或 `--from`，但不能同时提供两个。

🌐 Either `--to` or `--from` is required, and you cannot pass both.

:::tip Tips

* 在对远程实例运行命令之前，为了熟悉该命令，请参阅[在本地测试数据传输](/cms/features/data-management/transfer-locally)。
* 将你的传输令牌存储到[环境变量](/cms/configurations/environment)中可能会更方便，以避免复制/粘贴。只需确保这些令牌不会被推送到公共仓库。

:::

## 生成传输令牌 {#generate-a-transfer-token}

🌐 Generate a transfer token

:::prerequisites

盐转移令牌应在[管理员面板配置](/cms/configurations/admin-panel)文件中定义。

🌐 A salt transfer token should be defined in the [admin panel configuration](/cms/configurations/admin-panel) file.

:::

`strapi transfer` 命令需要目标实例发放的传输令牌。要在管理面板中生成传输令牌，请按照 [用户指南](/cms/features/data-management#admin-panel-settings) 中的说明操作。

🌐 The `strapi transfer` command requires a transfer token issued by the destination instance. To generate a transfer token in the admin panel use the instructions in the [User Guide](/cms/features/data-management#admin-panel-settings).

令牌的转移可以在[管理面板](/cms/features/data-management#admin-panel-settings)中进行，你还可以在这里管理基于角色的令牌权限，包括 `view`、`create`、`read`、`regenerate` 和 `delete`。

🌐 Transfer tokens are [managed from the admin panel](/cms/features/data-management#admin-panel-settings), where you can also manage role-based permissions to tokens including `view`, `create`, `read`, `regenerate`, and `delete`.

## 设置并运行数据传输 {#setup-and-run-the-data-transfer}

🌐 Setup and run the data transfer

启动数据传输取决于你是要将数据推送到远程实例还是从远程拉取数据：

🌐 Initiating a data transfer depends on whether you want to push data to a remote instance or to pull data from the remote:

:::caution

远程 Strapi 实例必须用 `start` 命令运行，而不是 `develop` 命令。

🌐 The remote Strapi instance must be running with the `start` command, not the `develop` command.

:::

1. 启动目标实例的 Strapi 服务器。
  2. 在新的终端窗口中，导航到源实例的根目录。
  3. 运行以下最小命令以启动传输，确保 `destinationURL` 是管理面板的完整 URL（即 URL 包含 `/admin` 部分）：

    ```bash
    yarn strapi transfer --to destinationURL
    ```

    ```bash
    npm run strapi transfer -- --to destinationURL
    ```

  4. 当出现提示时添加转移令牌。
  5. 在命令行提示符下回答 **是** 或 **否**："传输将删除远程 Strapi 上的现有数据！你确定要继续吗？"

1. 启动源实例的 Strapi 服务器。
2. 在新的终端窗口中，导航到目标实例的根目录。
  3. 运行以下最小命令以启动传输，确保 `remoteURL` 是管理面板的完整 URL（即 URL 包含 `/admin` 部分）：

  ```bash
  yarn strapi transfer --from remoteURL
  ```

  ```bash
  npm run strapi transfer -- --from remoteURL
  ```

4. 当出现提示时添加转移令牌。
5. 在命令行提示符下回答 **是** 或 **否**：“此传输将删除所有本地 Strapi 资源及其数据库。你确定要继续吗？”

一旦传输开始，命令会在终端中实时报告进度，包括准备步骤、各阶段进度以及计时和预估剩余时间。

🌐 Once the transfer starts, the command reports live progress in the terminal, including preparation steps, per-stage progress, and timing with an estimated time remaining.

## 一次转移能替代和保留什么 {#what-a-transfer-replaces-and-preserves}

🌐 What a transfer replaces and preserves

`--only` 和 `--exclude` 缩小了传输的范围。两者都接收一个用逗号分隔且类型之间没有空格的字符串：`content`、`files` 和 `config`，另外 `media-library` 仅用于 `--exclude`。模式(schema)永远不能被排除，因为模式匹配用于 `strapi transfer`。

当你使用任一选项时，只有你指定的阶段会在目标上受到影响：

🌐 When you use either option, only the stages you name are affected on the destination:

- **被省略的阶段会被保留。** 当一个阶段未被传输时，该阶段的目标数据将保持不变。
- **已转移的阶段将被替换。** 你在转移中包含的任何阶段都会完全替换该阶段的目标数据，除了管理员类型和被忽略的类型，如 `plugin::content-releases.release`，这些类型总是会被保留。

阶段过滤和内容类型过滤是独立的，可以组合使用。阶段过滤器（`--only` 和 `--exclude`）用来选择哪些类型的数据可以移动。内容类型过滤器（`--only-content-types` 和 `--exclude-content-types`）则限制在内容阶段可以移动的内容类型。

🌐 Stage filtering and content-type filtering are independent and can be combined. Stage filters (`--only` and `--exclude`) select which kinds of data move. Content-type filters (`--only-content-types` and `--exclude-content-types`) narrow which content types move within the content stage.

### 例如：在保留目标配置的同时刷新内容 {#example-refresh-content-while-preserving-destination-config}

🌐 Example: refresh content while preserving destination config

仅刷新源实例的内容，同时保留目标实例的配置：

🌐 To refresh only content from a source instance while keeping the destination instance's configuration:

```bash
yarn strapi transfer --to https://example.com/admin --to-token my-transfer-token --only content
```

```bash
npm run strapi transfer -- --to https://example.com/admin --to-token my-transfer-token --only content
```

每个预设对应不同的传输阶段：`content` 包括实体和链接，也就是内容类型行，包括媒体库数据库记录及其关联。`files` 涉及资源阶段，也就是 `public/uploads` 下的上传二进制文件。`config` 涵盖核心存储和 webhook。不管这些预设如何，模式总是会被传输。

🌐 Each preset maps to transfer stages: `content` covers entities and links, meaning content-type rows, including media library database records, and their relations. `files` covers the assets stage, meaning the upload binaries under `public/uploads`. `config` covers the core store and webhooks. Schemas are always transferred, independently of these presets.

:::warning

媒体分布在两个预设中。`files` 预设只涵盖二进制文件，而媒体库数据库记录（`plugin::upload.file` 和 `plugin::upload.folder`）属于 `content`。所以单独使用 `--exclude files` 只能跳过资源阶段：记录仍会被传输，目标端可能会出现指向从未传输的二进制文件的记录。要同时保留两者，请使用 `--exclude media-library`。

🌐 Media is split across two presets. The `files` preset covers only the binaries, while the media library database records (`plugin::upload.file` and `plugin::upload.folder`) belong to `content`. So `--exclude files` alone only skips the assets stage: the records still transfer, and the destination can end up with records pointing to binaries that were never transferred. To preserve both, use `--exclude media-library`.

:::

| 标志 | 已传输 | 目标上保留的内容 |
|-------|---------|-------------------|
| 默认 `strapi transfer` | 内容、文件、配置 | 仅管理员和忽略类型 |
| `--only content` | 内容 | 配置和上传的二进制文件 |
| `--only files` | 文件 | 内容和配置 |
| `--only config` | 配置 | 内容和文件 |
| `--only content,files` | 内容和文件 | 配置 |
| `--exclude content` | 文件和配置 | 内容 |
| `--exclude files` | 内容和配置 | 上传的二进制文件 |
| `--exclude media-library` | 不含上传类型的内容和配置 | 上传的二进制文件、`plugin::upload.file` 和 `plugin::upload.folder` |

### 示例：仅传输文件 {#example-only-transfer-files}

🌐 Example: only transfer files

```bash
yarn strapi transfer --to https://example.com/admin --only files
```

```bash
npm run strapi transfer -- --to https://example.com/admin --only files
```

### 示例：从传输中排除文件 {#example-exclude-files-from-transfer}

🌐 Example: exclude files from transfer

```bash
yarn strapi transfer --to https://example.com/admin --exclude files
```

```bash
npm run strapi transfer -- --to https://example.com/admin --exclude files
```

## 在传输过程中筛选内容类型 {#filter-content-types-during-transfer}

🌐 Filter content types during transfer

`--exclude-content-types` 和 `--only-content-types` 选项让你可以把传输限定到特定的内容类型。这两个选项都接受以逗号分隔的内容类型 UID 列表（例如 `api::article.article`）。未知的 UID 会在启动时根据 Strapi 的 schema 进行验证。所有实体记录以及涉及被排除类型的关系链接都会自动跳过。

🌐 The `--exclude-content-types` and `--only-content-types` options let you scope a transfer to specific content types. Both options accept a comma-separated list of content-type UIDs (for example, `api::article.article`). Unknown UIDs are validated against the Strapi schema at startup. Both entity records and any relation links touching an excluded type are skipped automatically.

:::warning Warning: Restore behavior

- 当你使用 `--exclude-content-types` 时，被排除类型的数据会在目标位置**保留**：在传输前不会被清除。
- 当你使用 `--only-content-types` 时，预传输清理只会针对列出的 UID，而其他目标上的内容会保持不变。

:::

### 例如：排除特定内容类型的传输 {#example-exclude-specific-content-types-from-transfer}

🌐 Example: exclude specific content types from transfer

```bash
yarn strapi transfer --to https://example.com/admin --to-token my-transfer-token \
  --exclude-content-types api::article.article
```

```bash
npm run strapi transfer -- --to https://example.com/admin --to-token my-transfer-token \
  --exclude-content-types api::article.article
```

### 例如：仅传输特定内容类型 {#example-transfer-only-specific-content-types}

🌐 Example: transfer only specific content types

```bash
yarn strapi transfer --to https://example.com/admin --to-token my-transfer-token \
  --only-content-types api::article.article,api::category.category
```

```bash
npm run strapi transfer -- --to https://example.com/admin --to-token my-transfer-token \
  --only-content-types api::article.article,api::category.category
```

## 绕过所有 `transfer` 命令行提示 {#bypass-all-transfer-command-line-prompts}

🌐 Bypass all `transfer` command line prompts

使用 `strapi transfer` 命令时，你需要确认转移操作会删除现有的数据库内容。`--force` 标志可以让你跳过这个提示。这个选项在以编程方式实现 `strapi transfer` 时很有用。如果你使用 `--force` 选项，必须在传输令牌中传入 `--to-token` 选项。

🌐 When using the `strapi transfer` command, you are required to confirm that the transfer will delete the existing database contents. The `--force` flag allows you to bypass this prompt. This option is useful for implementing `strapi transfer` programmatically. You must pass the `--to-token` option with the transfer token if you use the `--force` option.

:::caution

`--force` 选项会绕过所有关于内容删除的警告。删除只涵盖实际传输的阶段：如果你使用 `--only` 或 `--exclude` 过滤阶段，被省略的阶段会被保留。参见 [传输会替换和保留什么](#what-a-transfer-replaces-and-preserves)。

🌐 The `--force` option bypasses all warnings about content deletion. The deletion only covers the stages that are actually transferred: if you filter stages with `--only` or `--exclude`, the omitted stages are preserved. See [What a transfer replaces and preserves](#what-a-transfer-replaces-and-preserves).

:::

### 示例：使用 `--force` 绕过 `transfer` 命令行提示 {#example-bypass-the-transfer-command-line-prompts-with---force}

🌐 Example: bypass the `transfer` command line prompts with `--force`

```bash
yarn strapi transfer --to https://example.com/admin --to-token my-transfer-token --force
```

```bash
npm run strapi transfer -- --to https://example.com/admin --to-token my-transfer-token --force
```

## 音调转移性能与验证 {#tune-transfer-performance-and-verification}

🌐 Tune transfer performance and verification

有两个选项可以调整传输的运行方式，而不是它所传输的内容：

🌐 Two options adjust how a transfer runs rather than what it carries:

- `--no-checksums` 会禁用应用于资源的端到端 SHA-256 校验和验证。当源和目标都支持时，验证默认是开启的，它可以保证资源完整到达，所以只有在排查问题时才关闭它。
- `--verbose` 会打印详细日志，这在转账失败却没有明显原因时特别有用。

使用 `--from` 拉取时，资源流还取决于 `transfer.remote.assetIdleTimeoutMs` 服务器选项，它限制了在传输中资源流在没有前进的情况下可持续的最长时间，超时则会中止传输。默认值是 `300000`，也就是 5 分钟。详见 [服务器配置文档](/cms/configurations/server)。

🌐 When pulling with `--from`, asset streaming also depends on the `transfer.remote.assetIdleTimeoutMs` server option, which caps how long an asset stream may go without forward progress before the transfer aborts. It defaults to `300000`, meaning 5 minutes. See the [server configuration documentation](/cms/configurations/server).

### 示例：禁用校验和验证 {#example-disable-checksum-verification}

🌐 Example: disable checksum verification

```bash
yarn strapi transfer --to https://example.com/admin --to-token my-transfer-token \
  --no-checksums
```

```bash
npm run strapi transfer -- --to https://example.com/admin --to-token my-transfer-token \
  --no-checksums
```

## 禁用远程数据传输 {#disable-remote-data-transfer}

🌐 Disable remote data transfer

在 [服务器配置](/cms/configurations/server) 文件中使用 `transfer.remote.enabled` 选项可以禁用远程数据传输。结合管理面板中可用的 [RBAC 权限](/cms/features/rbac#configuring-roles-permissions)，这可以帮助你保护你的 Strapi 应用。

🌐 Remote data transfer is disabled with the `transfer.remote.enabled` option in the [server configuration](/cms/configurations/server) file. Combined with the [RBAC permissions](/cms/features/rbac#configuring-roles-permissions) available in the admin panel, this can help you secure your Strapi application.

```js title="/config/server.js"
module.exports = ({ env }) => ({
  // …
  transfer: {
    remote: {
      enabled: false,
    },
  },
});
```

:::caution

在 Strapi v4 中，这由 `STRAPI_DISABLE_REMOTE_DATA_TRANSFER` 环境变量控制，但现在不再支持：设置它会显示警告，并且不会有任何效果。参见 [已移除对某些环境选项的支持](/cms/migration/v4-to-v5/breaking-changes/removed-support-for-some-env-options)。

🌐 In Strapi v4 this was controlled by the `STRAPI_DISABLE_REMOTE_DATA_TRANSFER` environment variable, which is no longer supported: setting it now logs a warning and has no effect. See [Removed support for some environment options](/cms/migration/v4-to-v5/breaking-changes/removed-support-for-some-env-options).

:::

## 故障排除 {#troubleshooting}

🌐 Troubleshooting

**在 nginx 反向代理后传输失败。** 一个传输会打开 WebSocket 连接，当代理不转发连接升级时会失败。[Nginx 指南](/cms/deployment/guides/nginx) 中的服务器块通过 `proxy_http_version 1.1` 以及 `Upgrade` 和 `Connection` 头部转发它。两者都是必需的：没有 `proxy_http_version 1.1` 升级根本不会发生，无论设置了哪些头部。

**连接被拒绝，目标是 `localhost`。** 尝试将地址改为  [http://127.0.0.1:1337/admin](http://127.0.0.1:1337/admin)。

**传输失败，并且项目使用了 websockets。** 当使用 websockets 或 Socket.io 时，`transfer` 命令会失败。可以暂时禁用它们，或者确保 websocket 服务器运行在与 Strapi 服务器不同的端口，或者在 Strapi 内的特定路由上运行。
