---
title: Web App 集成
description: 如何在客户端集成 Web & SDK 合约——重定向流与 iFrame SDK 配置。
canonical: https://developer.unico.io/zh-CN/developers/sdks-and-tools/web/
locale: zh-CN
generated_by: markdown-export
---

- [/zh-CN/](/zh-CN/)
- [SDK 与工具](/zh-CN/developers/sdks-and-tools/overview)
- 网页应用集成

**本页内容# Web App 集成

本页介绍 Unico 旅程的工作方式，以及可用于将其集成到应用程序中的集成模型。
**旅程**是用户为完成身份验证而经历的一系列步骤。例如：拍摄证件照片和进行人脸采集（活体检测）。
Unico 负责管理整个体验。集成所需的工作量极小：旅程通过 **CreateProcess** 创建，用户被引导至该旅程，并在最后接收结果。中间发生的一切（界面、提示、校验）都已构建完成并由 Unico 维护。
## 两种集成模型​

每个客户的需求各不相同。Unico 提供**两种模型**来引导用户进入旅程。
模型适用于**Journeys SDK**需要集成、无缝体验，并希望让用户保持在同一环境中的 Web 应用**直接访问**旅程可以在主页面之外进行的 Web 流程，或已嵌入 WebView 的应用。原生应用应优先使用对应平台的 SDK
原生应用如果你的应用程序是原生移动应用，我们建议使用其所构建平台（[Android](/zh-CN/developers/sdks-and-tools/android/requirements)、[iOS](/zh-CN/developers/sdks-and-tools/ios/requirements) 或 [Flutter](/zh-CN/developers/sdks-and-tools/flutter/requirements)）对应的 SDK，而不是采用 Web 集成。
Journeys SDK直接访问旅程在**应用程序自身内部**进行，不会让用户离开其上下文。**Journeys SDK** 安装在应用程序中，用于在需要时打开旅程。这是实现更加集成、无缝体验的推荐路径，让用户始终保持在同一环境中，从而往往能减少整个流程中的摩擦和流失。Unico 提供了一个与现代浏览器兼容的 JavaScript 库，只需几行代码即可将旅程集成到几乎任何应用程序中。### 兼容性​

该库的设计目标是无摩擦地融入任何项目，无论使用何种技术栈：
**任何 Web 应用。** 以 UMD 格式分发，可在通过现代打包工具（如 webpack 或 Vite）导入时工作。与任何框架（React、Angular、Vue）或纯 JavaScript 兼容。
**现代浏览器。** 该库已包含 Promises 和 `async/await` 等特性所需的 polyfill，从而将兼容性扩展到较旧版本的浏览器。
**标准 Web API。** 旅程基于浏览器的原生能力运行，不依赖项目中的插件或外部库。
### SDK 的内部工作原理​

打开旅程时，SDK 会将一个 iFrame 插入页面，并从那一刻起接管整个视觉体验。每个步骤的界面、脚本和资源都在该 iFrame 内运行，从用户开始的那一刻直到流程完成。这一架构决策是有意为之的：iFrame 隔离确保 Unico 旅程不会干扰应用程序的样式或行为。没有任何脚本会泄漏到外部上下文，也没有任何 CSS 规则会与应用程序自身的样式冲突。其结果是为最终用户带来一致的体验，并将对客户产品的影响降到最低。由于 Unico 负责创建和管理 iFrame，旅程的改进（无论是性能、体验还是校验方面）都会自动交付给所有用户，而无需对已集成的应用程序进行任何更改。集成将始终以可用的最佳优化运行，无需跟踪或响应平台的每次演进。### 开始使用​

**步骤 1**：安装`unico-journey-sdk` 包在 IDPay 支付旅程和身份验证旅程之间共享。对于身份验证用例，请按照下面步骤所示导入 `ByUnicoSDK` 类。```
  npm install unico-journey-sdk
```

曾用名 idpay-b2b-sdk此软件包之前以 `idpay-b2b-sdk` 名称发布。它是同一个 SDK，只是采用了新的名称，并沿用相同的版本线。新名称下仅提供 **2.3.0 及更高版本**——完整历史请参阅[发布说明](/zh-CN/developers/sdks-and-tools/web/resources/release-notes)。安装 Journeys SDK 的推荐方式是通过 **npm** 或 **yarn** 等依赖管理器，从 **npm registry** 上提供的包进行安装。这种方式不仅简化了安装和依赖管理，还能清晰地控制所使用的版本，并便于在每次发布新版本时进行更新。SDK 遵循**语义化版本控制（SemVer）**，这意味着 patch 和 minor 更新不会引入破坏性变更。可以安全地将项目配置为自动接收这些更新。可能需要调整集成的变更会保留给 major 版本，并始终附带迁移指南。保持 SDK 为最新版本保持最新版本之所以特别重要，有两个原因。第一是**安全性**：每当发现漏洞或出现加强通信协议的机会时，都会发布安全补丁。运行过时的版本意味着放弃这些修复，并使流程暴露于不必要的风险之中。第二是**稳定性**：错误修复也以相同方式分发，旧版本可能存在在较新版本中已解决的行为。开始之前，请向 Unico 支持团队注册你的域名。所有域名都必须使用 HTTPS。**步骤 2**：调用 `init(options)`初始化 SDK 并预加载旅程正确运行所需的脚本，为最终用户带来更流畅的体验。请在流程中尽早调用它。参数必填说明`token`是Create Process API 返回的流程令牌`env`否仅在测试环境中设置为 `'uat'````
import { ByUnicoSDK } from 'unico-journey-sdk';ByUnicoSDK.init({  token,  // env: 'uat' // 仅用于测试环境});
```

**步骤 3**：调用 `open(options)`显示 iFrame 并为用户启动旅程。从此刻起，一切都在 iFrame 内部自动进行，无需管理任何中间步骤。参数必填说明`transactionId`是Create Process API 返回的流程 ID`token`是Create Process API 返回的流程令牌`onFinish`是旅程结束或被关闭时执行的回调`onWidgetVisibilityChange`否小组件可见状态变化时执行的回调与应用程序的下一次交互发生在旅程结束时，无论用户是完成了它还是关闭了它。届时，SDK 会调用作为参数传入 `open` 的 **`onFinish`** 回调。此后，应用程序可以调用 **`getProcess`** API 来检查结果，或者在更倾向于异步方式时等待 **Webhook** 通知。除了查询结果之外，建议使用 `onFinish` 来处理应用程序的前端状态：
**避免循环。** 防止在旅程结束后用户立即再次触发流程时，进程被立即且不必要地重新创建。
**流程管理。** 确保用户被引导至应用程序的下一步，避免在旅程关闭后停留在无法退出的界面上。
警告`onFinish` 回调表示用户已完成旅程，但并不保证审批通过。流程可能因 Unico 某条校验规则未通过而结束。通过 `getProcess` 查询或接收 Webhook 通知并非可选项：它们是实际结果的唯一来源，应用程序的行为必须以此为依据。不得单独使用 `onFinish` 来判断用户是否获得批准。`onFinish` 回调会接收一个描述旅程如何结束的对象：字段类型说明`type`string旅程结束的方式：`'FINISH'`（已完成）或 `'CLOSE'`（用户在完成前关闭）`transaction`object | undefined当 `type` 为 `'FINISH'` 时存在；当 `type` 为 `'CLOSE'` 时为 `undefined``transaction.id`string流程标识符（与传入的 `transactionId` 相同）`transaction.​redirectUrl`string旅程结束后重定向用户的 URL处理 **`onWidgetVisibilityChange`** 回调是可选的，对你的用例可能并不相关。每当小组件的可见状态发生变化时都会调用它，且仅在一种特定场景下有用：某些旅程会显示透明背景，使应用程序页面在体验后面保持可见。在验证流程中显示自有模态框的应用程序（例如，作为多个 KYC 提供商之间编排的一部分）可能最终会将该模态框显示在 Unico 小组件后面，从而降低视觉体验。在这种情况下，该回调允许应用程序在 Unico 旅程处于活动状态时隐藏任何额外的视觉元素，并在结束后恢复它们。如果你的应用程序没有任何可能与小组件重叠的 UI，则可以放心地省略它。```
ByUnicoSDK.open({  transactionId: '9bc22bac-1e64-49a5-94d6-9e4f8ec9a1bf',  token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',  onFinish: ({ transaction, type }) => {    if (type === 'FINISH') {      // 旅程已完成（transaction = { id, redirectUrl }）：在此继续你的流程。    }    // type === 'CLOSE' → 用户在完成前关闭；  },  // 可选：仅当你的应用显示可能与小组件重叠的 UI 时才需要。  onWidgetVisibilityChange: (visible) => {    // 根据小组件可见性隐藏或恢复你的模态框  },});// 如需随时显式关闭 SDK：ByUnicoSDK.close();
```

下面的时序图展示了如何使用 SDK 和 API 结果来配置 iFrame：### 参考应用​

语言 / 框架描述仓库Node.js (Express)使用 Journeys SDK 实现完整用户旅程流程的 Node.js 参考应用[GitHub — reference-apps/web](https://github.com/unico-labs/reference-apps/tree/main/web)### 安全性​

该模型中的安全性是分层构建的，从 SDK 与在 iFrame 内部运行的应用程序之间的通信协议开始。旅程加载时，双方会执行**握手（handshake）**以建立通信。在此过程中，Unico 应用程序会将通过 `postMessage` 接收到的数据注入消息的来源，与按环境（UAT 和 PROD）划分的授权域名封闭列表进行校验。来自未经批准来源的消息会被立即丢弃，从而防止旅程被嵌入到未经授权的页面中，并消除诸如**点击劫持（clickjacking）**等漏洞的攻击面。除来源校验外，流程仅在持有有效交易令牌时才会继续：这是一个由 Unico 后端签发并签名的一次性 JWT。这确保了即使是已授权的来源，也无法使用已过期、被重复使用或被伪造的令牌进行操作。握手完成后，令牌会被注入 iFrame，双方之间不再传输任何敏感信息。其余所有通信仅用于界面控制（打开、关闭和界面切换），从而防止流程数据在旅程期间被拦截或泄露。iFrame 隔离还在运行时保护 Unico 脚本的完整性。由于代码在与页面分  离的上下文中运行，外部脚本无法访问或修改它，从而确保旅程严格按照其构建方式运行，不受干扰。按照设计，本集成模型不采用 CSP。授权域名是每个客户安全配置的一部分，将其在标头中公开可能会让恶意行为者更容易绘制基础设施的图谱。由于客户识别仅在 `init` 时才发生，因此无法在此之前将这些域名动态注入标头，这使得在不放弃此隐私性的前提下无法使用 CSP。所有安全保障均由上述握手协议提供。### SDK 专属故障排查​

本节介绍集成过程中最常见的问题以及推荐的排查方法。#### 意外行为或流程中断​

请检查是否有应用程序脚本在 DOM 中直接操作 iFrame。SDK 在页面的 `body` 中创建并管理 iFrame，任何外部修改（无论是作用域、定位还是属性方面）都可能干扰旅程的生命周期并导致不可预测的行为。#### 视觉体验与预期不符​

请检查是否有应用程序的全局样式表覆盖了 iFrame 内部的属性。SDK 使用动态 ID 和以 `unico` 为前缀的类来创建 iFrame 及其所有内部元素，从而显著降低通过 ID 或类选择器产  生冲突的风险。即便如此，作用域较广的 CSS 规则（例如标签选择器）仍可能触及 iFrame 内部的元素，并改变呈现给用户的视觉体验。#### 直接修改了 SDK 库文件​

请检查是否有库文件在依赖管理器之外被修改。该库必须仅通过 **npm** 或 **yarn** 管理，不得直接编辑已安装的文件。手动修改可能产生难以复现的异常行为，并使 Unico 支持无法提供协助。用户被**重定向到由 Unico 托管的链接**，旅程在该处进行。完成后，用户会返回到创建流程时定义的 URL（`callbackUri` 参数）。这是最易于采用的方式：无需安装任何库，并且在旅程不需要发生在应用程序自身页面内时效果良好。另一方面，将用户带离客户的环境往往会带来更多摩擦，从而导致更高的流失率。创建流程后，API 响应中会包含由 Unico 托管的旅程 URL。有两种常见的方式可将用户引导至该 URL：
**标准重定向。** 用户被直接重定向到旅程 URL。完成后，Unico 会将其重定向回创建流程时定义的 `callbackUri`。
**使用 `window.open()` 打开新标签页。** 旅程在新的浏览器标签页中打开，使用户保持在独立的上下文中。在这种情况下，建议监听 URL 变化为 `callbackUri`，并在流程完成后关闭标签页。有关该 API 的详细信息，请参阅 [MDN 文档](https://developer.mozilla.org/en-US/docs/Web/API/Window/open)。
在移动应用中，通常使用 **WebView** 直接打开旅程，无需额外的重定向。在这种情况下，`callbackUri` 还接受 **deeplink**，从而允许旅程完成后触发打开原生应用中的特定界面。只需将 deeplink 配置为返回目标，操作系统就会负责将用户路由到正确的位置。这种 WebView 方式适用于已经嵌入 WebView 的应用；完全原生的应用则应优先使用对应平台的 SDK。
#### 进行采集测试时请勿打开 DevTools​

Unico 使用多种机制来保护其旅程的安全，其中之一会将打开的 DevTools 检测为潜在的欺诈信号并阻止提交。运行端到端采集测试前请关闭 DevTools。
不受支持的集成本文档中描述的模型（直接访问和 Journeys SDK）是 Unico 官方支持的唯一集成方式。偏离这些标准的集成可能导致意外行为、安全流程失败和旅程中断，并且不在 Unico 支持范围之内。一些不受支持的方式示例：
在移动应用中**将 SDK 嵌入 WebView 内**。在这些情况下，正确的方式是使用**直接访问**模型，直接在 WebView 中打开旅程链接，而不涉及 Journeys SDK。
不经过 Journeys SDK，**直接通过 HTML `<iframe>` 标签加载 iFrame**。iFrame 是 SDK 的内部实现细节，不得手动实例化。正确的方式是使用 **Journeys SDK**，由它安全地、在预期标准范围内管理 iFrame 的生命周期。
如果对某种方式是否在受支持的标准范围内有任何疑问，请在继续实施之前查阅文档或联系支持团队。最后更新 于 2026年10月23日**