2026-06-16 12:14:52 +08:00
|
|
|
|
# @xuqm/rn-xwebview
|
|
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
通用 React Native WebView 容器。`1.0.0` 只有三项正式入口:
|
2026-07-20 19:31:43 +08:00
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
- `<XWebViewHost />`:应用根部挂载一次的全屏页面 Host。
|
|
|
|
|
|
- `openWebView(config)`:从任意业务服务打开页面,返回该页面自己的 Handle。
|
|
|
|
|
|
- `<XWebViewView config={...} />`:不需要全屏导航栏时使用的内嵌浏览器内核。
|
2026-07-18 06:59:57 +08:00
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
SDK 不包含任何医网信、厂商、用户、平台、域名或业务 Bridge 定义。
|
2026-06-16 12:14:52 +08:00
|
|
|
|
|
|
|
|
|
|
## 安装
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-17 13:50:30 +08:00
|
|
|
|
pnpm add @xuqm/rn-common @xuqm/rn-xwebview \
|
2026-07-26 19:41:03 +08:00
|
|
|
|
react-native-webview react-native-svg \
|
|
|
|
|
|
@react-native-clipboard/clipboard react-native-safe-area-context
|
2026-06-16 12:14:52 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
`react-native-svg` 含原生 ViewManager,必须由宿主直接声明并完成 React Native
|
|
|
|
|
|
autolink;它不能只作为 `@xuqm/rn-xwebview` 的传递依赖。缺少该直接依赖时,使用
|
|
|
|
|
|
SDK 内置导航图标的页面会在运行期报告找不到 `RNSVGSvgViewAndroid`。
|
|
|
|
|
|
|
|
|
|
|
|
`@react-native-camera-roll/camera-roll` 是可选 peer;只有需要把下载图片登记到系统相册
|
|
|
|
|
|
时才安装。
|
|
|
|
|
|
|
|
|
|
|
|
## 最小集成
|
2026-06-16 12:14:52 +08:00
|
|
|
|
|
|
|
|
|
|
```tsx
|
2026-07-26 19:41:03 +08:00
|
|
|
|
import { XWebViewHost, openWebView } from '@xuqm/rn-xwebview'
|
2026-06-16 12:14:52 +08:00
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
export function App() {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<RootNavigation />
|
|
|
|
|
|
<XWebViewHost />
|
|
|
|
|
|
</>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const page = openWebView({
|
|
|
|
|
|
source: { uri: 'https://example.com' },
|
|
|
|
|
|
navigationBar: {
|
|
|
|
|
|
title: { text: '页面标题', mode: 'web' },
|
|
|
|
|
|
},
|
|
|
|
|
|
statusBar: {
|
|
|
|
|
|
translucent: true,
|
2026-07-18 06:59:57 +08:00
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
page.reload()
|
|
|
|
|
|
page.postMessage('hello')
|
|
|
|
|
|
page.close()
|
|
|
|
|
|
const result = await page.closed
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Host 尚未挂载时请求最多等待 3 秒,超时以 `host_unavailable` 关闭。全局只能挂载一个
|
|
|
|
|
|
Host;Host 卸载会以 `host_unmounted` 关闭其全部页面。
|
|
|
|
|
|
|
|
|
|
|
|
## 分组配置
|
|
|
|
|
|
|
|
|
|
|
|
`openWebView` 与 `XWebViewView` 使用同一个 `XWebViewConfig`:
|
|
|
|
|
|
|
|
|
|
|
|
- `source`:`{uri, headers?}` 与 `{html, baseUrl?}` 二选一。
|
|
|
|
|
|
- `navigationBar`:标题、返回、关闭、菜单、纯色/渐变/图片背景或完整自定义渲染。
|
|
|
|
|
|
- `statusBar`:显隐、透明沉浸、背景和前景模式。
|
|
|
|
|
|
- `behavior`:Cookie、混合内容、外链决策、JS 注入、消息与生命周期回调。
|
|
|
|
|
|
- `permissions`:摄像头/麦克风白名单与可选宿主决策。
|
|
|
|
|
|
- `downloads`:自动/人工决策、目标目录、鉴权头、进度、完成和失败回调。
|
|
|
|
|
|
- `bridge`:由具体业务协议包提供;XWebView 只负责转发与页面上下文。
|
|
|
|
|
|
|
|
|
|
|
|
禁止恢复扁平的 `url/title/showTopBar` 双轨配置。
|
|
|
|
|
|
|
|
|
|
|
|
## 页面栈与系统返回
|
|
|
|
|
|
|
|
|
|
|
|
每次 `openWebView` 都生成独立页面和 Handle。页面栈只显示顶层页面,关闭后恢复下一层
|
|
|
|
|
|
页面及其导航状态。Android 系统返回先执行网页历史返回,没有历史才关闭当前页。
|
|
|
|
|
|
|
|
|
|
|
|
导航标题和显隐修改属于当前页面,不能污染下层页面。H5 隐藏原生导航栏但保留状态栏
|
|
|
|
|
|
时,Bridge 可以从页面上下文取得真实安全区高度。
|
|
|
|
|
|
|
|
|
|
|
|
## 权限
|
|
|
|
|
|
|
|
|
|
|
|
SDK 不向 Manifest/Info.plist 注入敏感权限。宿主按启用能力声明,例如 Android:
|
|
|
|
|
|
|
|
|
|
|
|
```xml
|
|
|
|
|
|
<uses-permission android:name="android.permission.CAMERA" />
|
|
|
|
|
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
2026-06-16 12:14:52 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
H5 调用 `getUserMedia` 时,XWebView 先检查页面配置和宿主决策,再在 Android 请求系统
|
|
|
|
|
|
权限,最后才继续 WebView 媒体请求。未识别资源和 3 秒内未完成的自定义决策均拒绝。
|
2026-07-18 06:59:57 +08:00
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
## 下载与安全默认值
|
2026-06-22 17:43:00 +08:00
|
|
|
|
|
2026-07-26 19:41:03 +08:00
|
|
|
|
- 默认保存到 App 沙盒;`publicDownloads` 在 Android 使用沙盒落盘后登记到下载列表。
|
|
|
|
|
|
- URI 首屏 headers 自动复用于 HEAD 与文件下载,也可由 `downloads.headers` 补充。
|
|
|
|
|
|
- Cookie 默认共享,第三方 Cookie 默认关闭。
|
|
|
|
|
|
- 混合内容默认 `never`;生产页面不得改为 `always`。
|
|
|
|
|
|
- `http/https/about:blank` 在容器内打开;`tel/sms/mailto` 交给系统;`file/javascript/intent`
|
|
|
|
|
|
和未知 scheme 默认拒绝。
|
|
|
|
|
|
- Bridge 异常不会形成未处理 Promise;宿主可通过 `behavior.onBridgeError` 接收不含原始
|
|
|
|
|
|
payload 的错误信息。
|
|
|
|
|
|
|
|
|
|
|
|
## 迁移到 1.0.0
|
|
|
|
|
|
|
|
|
|
|
|
旧的 `XWebViewScreen`、`XWebViewControl`、`openXWebView(navigate, flatConfig)` 和
|
|
|
|
|
|
common 内的 WebView Bridge 已删除,不提供兼容壳。
|
|
|
|
|
|
|
|
|
|
|
|
迁移原则:
|
|
|
|
|
|
|
|
|
|
|
|
1. 根部挂载一次 `<XWebViewHost />`。
|
|
|
|
|
|
2. 扁平参数转换为上述分组配置。
|
|
|
|
|
|
3. 全局 Control 改为保存本次 `openWebView` 返回的页面 Handle。
|
|
|
|
|
|
4. 业务 Bridge 单独作为 `config.bridge` 注入,不进入 common 或 XWebView。
|
|
|
|
|
|
5. 内嵌页面直接使用 `<XWebViewView />`,不再直接包装 `react-native-webview`。
|
|
|
|
|
|
|
|
|
|
|
|
## 验证
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
pnpm --dir packages/xwebview typecheck
|
|
|
|
|
|
pnpm --dir packages/xwebview test
|
|
|
|
|
|
```
|