## 是否支持自定义安全策略？

是的。交互式API不使用 [`eval()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval) 或 [`Function()`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/Function) 构造函数，因此不会违反 [`unsafe-eval`](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy#unsafe_keyword_values) 内容安全策略。该API在设计上可与任何[自定义内容安全策略](https://developer.wordpress.org/apis/security/)协同工作。

## 能否使用指令发起AJAX/REST-API请求？

当然可以。通过指令调用的操作和回调函数可以执行任何JavaScript函数能实现的功能，包括发起API请求。

## 交互性API能否在区块之外使用？

当然可以，它不仅限于区块。虽然你会看到许多关于交互性API如何为创建交互式区块提供标准的讨论，但这只是因为那是最常见的用例。更广义地说，交互性API标准可用于为WordPress任何部分的前端添加“交互行为”。

有关在区块外使用任意HTML的交互性API的详细信息，请参阅[`wp_interactivity_process_directives`函数](https://developer.wordpress.org/reference/functions/wp_interactivity_process_directives/)。

## 这是否意味着我必须将所有交互式区块迁移到此API？

不需要。未使用交互性API的区块可以与使用该API的区块共存。但如前所述，请注意使用该API的区块具有以下优势：

- **区块间可轻松通信**：采用标准后，这种通信默认即可实现。当不同区块使用不同方法实现前端交互时，区块间通信会变得复杂，尤其在由不同开发者创建区块时几乎无法实现。
- **可组合性与兼容性**：你可以组合交互式区块，将其嵌套在具有定义行为的结构中，并且由于遵循相同标准，它们完全跨兼容。如果每个区块采用不同的交互方法，很可能会导致功能冲突。
- **减少向浏览器传输的数据量**：如果每个插件作者使用不同的JS框架，前端将加载更多代码。如果所有区块使用同一框架，代码可实现复用。
- 若页面所有区块都采用此标准，则可启用站点级功能（如客户端导航）。

## 使用此API对性能有何影响？对于非常简单的用例，加载交互性API是否值得？

该API在设计时已充分考虑性能因素：

- **指令所需的运行时代码仅约10KB**，且所有区块只需加载一次。
- **所有属于交互性API的脚本模块（包括`view.js`文件）均不会阻塞页面渲染。**
- 目前正在[持续探索](https://github.com/WordPress/gutenberg/discussions/52723)**在区块进入视口后延迟加载脚本**的可能性。通过这种方式，可在不影响用户体验的前提下优化初始加载。

## 是否与核心翻译API兼容？

由于交互性API与服务器端渲染完美配合，你可以使用所有WordPress API，包括[`__()`](https://developer.wordpress.org/reference/functions/__/)和[`_e()`](https://developer.wordpress.org/reference/functions/_e/)。你可以用它翻译HTML中的文本（就像通常做法），甚至可以在[服务器端使用`wp_interactivity_state()`](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/api-reference/#setting-the-store)时在存储库中使用。示例如下：

```php
// render.php
wp_interactivity_state( 'favoriteMovies', array(
      "1" => array(
        "id" => "123-abc",
        "movieName" => __("影片名称", "textdomain")
      ),
) );
```

目前正在开发与脚本模块（交互性API所需）兼容的翻译API。请关注[#60234](https://core.trac.wordpress.org/ticket/60234)了解进展。

## 我担心XSS攻击；JavaScript能否被注入到指令中？

不会。交互性API只允许将[引用](https://developer.wordpress.org/block-editor/reference-guides/interactivity-api/api-reference/#values-of-directives-are-references-to-store-properties)作为值传递给指令。这种方式无需eval()完整的JavaScript表达式，因此不可能实施XSS攻击。

### 原生 JavaScript

请参阅下方答案。

### 模板领域特定语言

我们还研究了创建用于编写交互式模板的[领域特定语言](https://en.wikipedia.org/wiki/Domain-specific_language)的可能性。使用该模板DSL编写的代码将被编译为JavaScript和PHP。然而，创建生产级的模板编译器十分复杂，需要投入大量精力且存在较高风险。未来仍会考虑采用这种方案，届时指令系统将作为编译目标。

## 作为区块开发者，为何应选择交互式API而非React？

在PHP服务端渲染环境中，前端使用React无法流畅运行。所有基于React渲染区块的方案都需通过客户端JavaScript加载内容。若仅通过客户端渲染区块，通常会导致用户体验不佳——用户需要盯着空白占位符和加载动画等待内容呈现。

虽然可通过PHP扩展（如v8js）运行JS，但遗憾的是PHP扩展不具向后兼容性，且必须存在PHP降级方案时才能使用。

当前虽可实现在PHP中服务端渲染区块，并同时在前端使用React渲染相同区块，但这会导致开发体验恶化——相同逻辑需在PHP和React部分重复实现。更严重的是，您将面临WordPress钩子引发的隐蔽错误！

假设安装的第三方插件通过钩子（过滤器）修改了服务端渲染的HTML，例如为区块HTML添加单个CSS类。该CSS类会存在于服务端渲染的标记中。但在前端，您的区块通过React重新渲染时，由于无法对React渲染内容应用WordPress钩子，最终呈现的内容将缺失这个CSS类！

反观交互式API，其设计理念是通过指令为服务端渲染的HTML增强交互行为，因此能与WordPress钩子完美协同。这也意味着它可以开箱即用地兼容WordPress后端API（如i18n）。

总结而言，选择交互式API而非单纯使用React具有以下优势：

- 使用React时，交互式区块在客户端生成的标记必须与服务端PHP生成的完全一致。而交互式API无此限制，指令可直接附加于服务端渲染的HTML
- 交互式API对PHP更友好，可无缝兼容WordPress钩子及其他服务端功能（如国际化）。例如使用React时，您无法预知服务端应用的钩子，其修改效果将在水合后被覆盖
- 具备[采用标准化方案](/docs/reference-guides/interactivity-api/iapi-about.md#why-a-standard)的所有优势

## 与jQuery或原生JavaScript相比，交互式API的优势何在？

核心差异在于交互式API具备**声明式与响应式特性**，这使得编写和维护复杂交互体验变得更为轻松。此外，它**专为区块开发量身定制**，提供的标准规范具备前述各项优势，包括区块间通信、兼容性以及客户端导航等全站功能。

最后与jQuery对比：**交互式API运行时仅约10kb**，体积更轻量化。实际上，WordPress生态正在持续推进移除jQuery等重型框架的工作，本API将为此提供助力。

## 是否需要同时掌握React、PHP和本交互式API？

若希望使用本API为区块添加前端交互功能，简短答案是肯定的。如果区块无需交互功能，区块创建流程将完全保持不变。

交互式API引入了新的标准方法，以简化WordPress前端交互行为的集成。这意味着您仍需要使用React来处理区块的编辑器部分。

反之，若要创建交互式区块，采用交互式API后您无需处理复杂议题，例如工具链配置、WordPress集成、区块间通信或交互部件的服务端渲染。

# 常见问题解答

## 交互性 API 底层是如何运作的？

其三大核心组件包括：

- 采用 [Preact](https://preactjs.com/) 与 [Preact Signals](https://preactjs.com/guide/v10/signals/) 组合实现水合作用、客户端逻辑及客户端导航功能
- 可被客户端与服务端共同解析的 HTML 指令系统
- 由 [HTML 标签处理器](https://make.wordpress.org/core/2023/03/07/introducing-the-html-api-in-wordpress-6-2/) 处理的服务器端逻辑

## 为何选择 Preact 构建指令系统？为何不采用 React 或其他 JavaScript 框架？

在前端应用场景中（这也是交互性 API 的核心定位），Preact 相较于 React 及 Vue、Svelte、Solid 等框架具有显著优势：

- 体积轻量：包含 [钩子函数](https://preactjs.com/guide/v10/hooks/) 与 [信号系统](https://preactjs.com/blog/introducing-signals/) 仅 8kB
- 开箱即用的 DOM 差异化比较功能
- 通过可选钩子实现高度可扩展性，该特性被广泛应用于钩子函数、React 兼容层 (preact/compat) 及信号系统 (@preact/signals)，覆盖除 DOM 差异算法外的所有功能模块
- 核心团队技术实力雄厚且提供强力支持，并对 Preact 的“孤岛架构”应用模式表现出浓厚兴趣

## Gutenberg 编辑器是否会因交互性 API 采用 Preact 而从 React 迁移？

不会。目前暂无迁移计划。作为一个完全交互式应用，编辑器的功能需求与优势考量存在显著差异。虽然 Preact 提供完全兼容 React 生态的 [`@preact/compat`](https://preactjs.com/guide/v10/switching-to-preact/) 套件，且已被众多大型网络应用采纳，但在区块编辑器中使用 Preact 无法获得像交互性 API 在前端场景中的同等优势。

## 除指令系统外，还考虑过哪些替代方案？

我们曾评估多种替代方案，以下是部分方案的简要概述：

### React 及其他 JavaScript 框架

由于 Gutenberg 开发者对 React 更熟悉，该框架成为首要考量对象。其他主流 JS 框架如 Svelte、Vue.js 或 Angular 也在评估之列，但这些框架（包括 React）均存在与 PHP 环境兼容性不足、无法适配 WordPress 钩子系统或国际化需求的局限性。

### Alpine.js

Alpine.js 是优秀的框架方案，其诸多功能设计为交互性 API 带来重要启发。但该框架不支持服务端渲染 [指令](https://github.com/alpinejs/alpine/tree/d7f9d641f7a763c56c598d118bd189a406a22383/packages/docs/src/en/directives)，而为 WordPress 区块量身打造专属系统能带来更多收益。

最终选择 Preact 取代 Alpine.js 基于多重考量：更小的体积尺寸、更优的性能表现（特别是集成 [信号系统](https://preactjs.com/guide/v10/signals/) 后）、基于 Preact 声明式语法及工具链（钩子、信号）编写自定义指令、相比 Alpine.js 具有更充分的实战检验与更庞大的开发者社区。同时完美兼容 React（便于共享编辑器中的客户端渲染组件），并为交互性 API 提供开箱即用的最快 DOM 差异算法，包含 UI 状态保持功能。

更重要的是，依托 Preact 的底层支撑，交互性 API 可专注管理“最终呈现层”，从而更好适配 WordPress 的特殊需求。例如：为避免安全风险并确保符合严格的安全策略，指令内部禁止使用 JavaScript 表达式；所有 WordPress 指令均符合 HTML 属性规范标准。

<div class="callout callout-info">
  欢迎查阅 <a href="https://github.com/WordPress/gutenberg/discussions/53022#discussioncomment-4696611">《为何选择 Preact 而非 Alpine？》</a> 专题讨论获取更多信息。
</div>