
Strapi Remote Destination Provider 详解通过 WebSocket 将数据推送到远程 Strapi 实例【免费下载链接】strapi Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.项目地址: https://gitcode.com/GitHub_Trending/st/strapiStrapi 的数据传输data-transfer模块支持在多个 Strapi 实例之间整站迁移内容、媒体与配置。其中 remote destination provider远程目标提供者负责把本机数据通过 WebSocket 推送到远端 Strapi并在传输的各个阶段assets、entities、links、configuration之间协调状态流转。本文基于官方文档对该 provider 的选项定义并结合 remote-destination 源码、dispatcher 工具与 CLI 命令逐层展开读完后你将掌握该 provider 的全部配置项restore、strategy、url、auth、retryMessageOptions、认证与安全前提、底层推送协议与批处理策略并知道如何通过strapi transfer命令实际操作。1. Provider 定位数据传输中的推方向在>export const TRANSFER_PATH /transfer/runner as const; export const TRANSFER_METHODS [push, pull] as const;destination 连接的是远端 admin URL 加/transfer/runner/push而 source 连接/transfer/runner/pull。远端真正落地数据的逻辑由 push handler 负责——从源码结构看PushHandler 内部复用了 local destination providercreateLocalStrapiDestinationProvider也就是说远程目标在远端最终退化成一个本地目标来写库这是理解整个 push 流程的关键。2. Provider 选项IRemoteStrapiDestinationProviderOptions文档给出的选项接口如下继承自 local destination provider 的restore与strategy另加远程专属项interface ITransferTokenAuth { type: token; // the name of the auth strategy token: string; // the transfer token } export interface IRemoteStrapiDestinationProviderOptions extends PickILocalStrapiDestinationProviderOptions, restore | strategy { url: URL; // the url of the remote Strapi admin auth?: ITransferTokenAuth; retryMessageOptions?: { retryMessageTimeout: number; // milliseconds to wait for a response from a message retryMessageMaxRetries: number; // max number of retries for a message before aborting transfer }; }各选项含义与源码中的补充细节选项类型说明strategyrestore冲突处理策略。从 local-destination 源码 可见VALID_CONFLICT_STRATEGIES [restore]即目前唯一可用的策略是 restore先清空目标数据再写入restorerestore.IRestoreOptions目标端清理选项。使用restore策略时为必需项从源码可见它支持按entities.include/entities.exclude筛选内容类型以及assets控制媒体清理范围urlURL远端 Strapi admin 的地址必须以http(s)协议书写见下节authITransferTokenAuth可选的 token 认证。不传时 provider 会尝试以公共访问方式连接retryMessageOptions对象消息级重试配置控制单条消息超时与最大重试次数默认值见第 5 节需要说明的是当前仓库源码中的接口比文档多了两项属于实现演进该文档标注为 experimentalonTransferPhase同样从 local providerPick过来用于向 CLI / UI 输出人类可读的传输阶段进度信息例如 bootstrap 时的 Remote: waiting for server to clear data and prepare destination…verifyChecksums?: boolean是否启用按文件的流式校验和并要求对端在接收时验证见第 7 节。auth的类型定义见 protocol/auth.ts目前唯一支持的认证策略就是token。3. URL 规则http(s) 写 URLws(s) 建连接文档特别强调url必须包含https或http协议provider 会将其转换为wss或ws来建立连接并且强烈建议使用安全连接因为 transfer token 拥有极高的访问权限。bootstrap 方法 中的具体实现印证了这一规则const { url, auth } this.options; const validProtocols [https:, http:]; if (!validProtocols.includes(url.protocol)) { throw new ProviderValidationError(Invalid protocol ${url.protocol}, { check: url, details: { protocol: url.protocol, validProtocols }, }); } const wsProtocol url.protocol https: ? wss: : ws:; const wsUrl ${wsProtocol}//${url.host}${trimTrailingSlash(url.pathname)}${TRANSFER_PATH}/push;要点有三直接传ws://或wss://的 URL 会抛出ProviderValidationErrorcheck: urlurl.pathname末尾的斜杠会被 trimTrailingSlash 去掉避免拼出双斜杠最终 WebSocket 地址 协议转换后的 host pathname /transfer/runner/push。这一行为有单测直接锁定index.test.ts 断言http://strapi.com/admin会连接ws://strapi.com/admin/transfer/runner/push、https://...会连接wss://...而ws://输入的 bootstrap 会以Invalid protocol报错拒绝。4. 认证transfer token 与 Bearer 头auth可选但强烈推荐。bootstrap 中对认证的分支处理如下见 bootstrap 源码// No auth defined, trying public access for transfer if (!auth) { ws await connectToWebsocket(wsUrl, undefined, this.#diagnostics); } // Common token auth, this should be the main auth method else if (auth.type token) { const headers { Authorization: Bearer ${auth.token} }; ws await connectToWebsocket(wsUrl, { headers }, this.#diagnostics); } // Invalid auth method provided else { throw new ProviderValidationError(Auth method not available, { ... }); }不传auth尝试公共访问适用于远端允许匿名 transfer 的配置auth.type token在 WebSocket 升级请求上附加Authorization: Bearer token头源码注释明确这是主要的认证方式其他auth.type直接抛ProviderValidationError。这里的 token 即 Strapi 后台生成的Transfer Token。在管理面板的 Settings 中可创建、查看与设置有效期见 TransferTokens 管理页面 与 token 服务远端通过>export const createDispatcher ( ws: WebSocket, retryMessageOptions: RetryMessageOptions { retryMessageMaxRetries: 5, retryMessageTimeout: 30000, // 30 秒 }, ... )即不显式传参时单条消息 30 秒未收到响应就重发最多重发 5 次仍无响应则以ProviderError(Request timed out)中止传输。从源码结构看其机制是每条消息带随机uuid发出后dispatcher 以retryMessageTimeout为周期重发同一份字符串化 payload直到收到uuid匹配的响应清除定时器或超过retryMessageMaxRetries。所有传输消息transfer action / step都会自动附带当前transferIDattachTransfer: true保证远端把消息挂到正确的传输会话上。bootstrap 阶段正是用这套 dispatcher 完成四件事见 bootstrap 尾部创建 dispatcher →initTransfer()拿到 transferID →setTransferProperties({ id, kind: push })→ 发送bootstrap动作等待远端就绪。6. init 协商策略下发与能力探测initTransfer 通过command: init把strategy、restore与transfer: push下发给远端远端据此初始化一次 push 传输并返回transferID。同一消息里还做两项能力协商校验和协商本地请求checksums: true时只有远端回显checksums: true才真正启用否则记录诊断警告 [Data transfer][push] Checksums were requested but the remote does not support checksum negotiation继续无校验和传输。资产块编码协商客户端始终声明assetEncoding: base64。若远端回显base64则使用紧凑的 base64 分块格式若不回显老版本远端会静默丢弃该字段则回退到 legacy 的{ type: Buffer, data: number[] }JSON 形状并输出警告说明大文件可能在远端JSON.parse时 OOM建议升级远端。这个版本兼容逻辑在源码注释中有明确说明引用了引入 base64 格式的 PR #23479。init响应中没有transferID时抛出ProviderTransferError(Init failed, invalid response from the server)。7. 推送流程阶段、批处理与统计核对拿到 transferID 后provider 通过createEntitiesWriteStream/createLinksWriteStream/createConfigurationWriteStream/createAssetsWriteStream四个写流接收引擎的数据每个写流对应一个传输阶段step消息按start → stream → end三段式发送#startStepdispatchTransferStep({ action: start, step })失败会把错误字符串或 Error包装为ProviderTransferError返回#streamStep发送{ action: stream, step, data }同时累加本地stats[step].count#endStep发送{ action: end }远端返回{ ok, stats }其中stats为远端的收发计数。非资产阶段的批处理entities / links / configuration由私有方法#writeStream实现源码给出了三个固定的批处理上限常量及其设计动机注释const STREAM_STEP_MAX_BATCH_BYTES 512 * 1024; // 单条消息载荷上限 512KB const STREAM_STEP_MAX_BATCH_ITEMS 100; // 单条消息条目上限 const STREAM_STEP_MAX_BATCH_AGE_MS 450; // 批次最老条目等待上限三者取先到者触发 flush批次 JSON 序列化后字节数 ≥ 512KB、条目数 ≥ 100、或首条数据已滞留 ≥ 450ms保证 UI 进度与网络进度差距有界。写入流关闭时先 flush 剩余批次再end并做一致性核对若远端返回的stats.started/stats.finished与本地发送计数count不一致回调报错Data missing: sent X entities, received Y and saved Z——即传输结束后会做一次端到端数量校验。资产阶段单独处理createAssetsWriteStream每个IAsset先推送{ action: start }含 filename、filepath、stats、metadata随后按流分块推送批次目标 1MB最后推送{ action: end }。启用verifyChecksums时分块过程中用createHash(sha256)增量计算哈希并在end消息中携带{ checksum: { algorithm: sha256, value } }供远端验证远端在 push handler 中维护assetChecksums增量状态与之对应。分块编码函数选择base64 或 legacy取决于第 6 节 init 协商的#assetEncoding结果。close()则负责优雅收尾发送close动作与command: end携带 transferID再等待 WebSocket 关闭见 close 实现。此外 provider 还暴露beforeTransfer()远端清数据与准备目标期间通过onTransferPhase汇报进度、rollback()、getMetadata()、getSchemas()分别对应 push 端合法动作清单[bootstrap, close, rollback, beforeTransfer, getMetadata, getSchemas]见 push.ts。8. 实战入口strapi transfer CLI上述 provider 的常规使用入口是strapi transfer命令命令定义在 transfer/command.ts实际路径为 packages/core/strapi/src/cli/commands/transfer/command.ts。与 destination 方向直接相关的选项有--to destinationURL目标远程 Strapi 的 URL解析为URL对象即本 provider 的url选项--to-token token目标端的 transfer token即auth.token--no-checksums禁用端到端资产校验和对应verifyChecksums--verbose、--force、--only/--exclude、--only-content-types/--exclude-content-types、--throttle等通用选项。命令行为要点均来自源码 preAction 钩子--from与--to只能二选一否则报错 Only one remote source (from) or destination (to) option may be provided--to的 URL 会被assertUrlHasProtocol校验必须带http(s)协议缺--to-token时会以密码输入方式交互式索取确认提示为 The transfer will delete existing data from the remote Strapi! Are you sure you want to proceed?——再次提醒 restore 策略对远端数据是破坏性的交互式场景下支持从环境变量STRAPI_TRANSFER_URL、STRAPI_TRANSFER_TOKEN读取配置未提供 URL 时会引导选择 push / pull 方向。一个典型的推送destination调用形态strapi transfer \ --to https://remote-strapi.example.com/admin \ --to-token transfer-token9. 小结与延伸阅读remote destination provider 把远程写库抽象成一次带认证的 WebSocket 会话http(s) URL 自动转 ws(s) 并拼接/transfer/runner/pushtoken 以 Bearer 头认证消息经具备默认 5 次 / 30 秒重试策略的 dispatcher 分发数据按阶段 start/stream/end 三段式推送并在批次上限512KB / 100 条 / 450ms与 1MB 资产批次之间做吞吐与延迟的平衡最后以远端 stats 做数量核对、可选 SHA-256 校验和兜底。安全上必须使用 https 连接妥善保管 transfer token因为该 token 足以清空并改写远端数据。相关文档与源码可继续深入协议与连接层文档01-websocket.md、02-source.md远端 push 处理与传输流程push.ts、flows/default.ts本地目标 providerrestore 策略实现local-destination/index.tsprovider 选项类型定义types/providers.ts测试参照remote-destination 单测、dispatcher 单测。【免费下载链接】strapi Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.项目地址: https://gitcode.com/GitHub_Trending/st/strapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考