一、网页跳转至 APP(鸿蒙设备)
1. App Linking
维度 | 要求 |
---|---|
域名 | 仅支持 HTTPS,且末尾禁止出现 / |
校验文件 | https://<domain>/.well-known/applinking.json |
签名 | 必须「手动签名」,自动签名会导致域名校验失败 |
applinking.json(部分示例)
{
"applinking": {
"apps": [
{ "appIdentifier": "1058xxxxx" } // AGC 上看的 APP ID
]
}
}
module.json5(关键片段)
"skills": [
{
"entities": ["entity.system.browsable"],
"actions": ["ohos.want.action.viewData"],
"uris": [
{ "scheme": "https", "host": "www.example.com", "pathPattern": ".*" }
],
"domainVerify": true
}
]
接收侧 ArkTS(EntryAbility.ets)
onCreate(want: Want): void {
const uri = want?.uri?.toString();
if (uri) {
// 跳详情页(router 在 18 仍可用)
const params = uri.split('?')[1];
AppStorage.set('deeplink', params);
windowStage.loadContent('pages/Detail');
}
}
网页侧(纯 HTML)
<a href="https://www.example.com/detail?sku=10086">在 App 打开</a>
若设备未装 App,系统会退回到浏览器打开同一地址;如 AGC 里勾选了「直达应用市场」,则直接跳「应用市场详情页」并携带「延迟链接」,安装后首次启动仍可还原到
sku=10086
详情页。
2. Deep Linking(自定义 scheme,仅作兼容)
优点 | 零服务端配置 |
---|---|
缺点 | 1. 未安装时无法 fallback;2. 易被拦截;3. 需要额外弹窗提示 |
module.json5
"uris": [{ "scheme": "demo", "host": "detail" }]
网页
<a href="demo://detail?sku=10086">打开 Demo App</a>
Deep Linking 不会触发域名校验,因此不会与 App Linking 冲突,可二者共存。
二、APP 跳转至网页(官方推荐)
1. 内嵌 ArkWeb(最常用)
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebPage {
ctrl = new webview.WebviewController();
build() {
Column() {
Web({ src: 'https://www.example.com', controller: this.ctrl })
.onLoadIntercept(e => {
// 如果想拦截外链可在此做路由
return false;
});
}
}
}
2. 系统浏览器/Custom Tabs(一次性跳出)
import { browser } from '@kit.ArkTS';
browser.loadCustomTabsUrl({
url: 'https://www.example.com',
options: { toolbarColor: '#FF6200EE' }
});
无需申请额外权限;
loadCustomTabsUrl
在 API 18 仍然为「华为私有接口」,非 OHOS 联盟规范,但已稳定开放。
三、双向数据通信(ArkWeb ⇄ ArkTS)
1. URL 参数(单向,网页→App)
2. JSBridge(双向,推荐)
App 侧注册
this.ctrl.registerJavaScriptProxy({
// 供网页调用的句柄
nativePay: (orderJson: string) => {
console.info('网页下单:' + orderJson);
// TODO 调起支付 SDK
return JSON.stringify({ code: 0 });
}
}, 'HarmonyBridge');
网页侧调用
<script>
window.HarmonyBridge.nativePay(JSON.stringify({sku:10086}));
</script>
App → Web
this.ctrl.runJavaScript(`refreshData('${JSON.stringify(newData)}')`);
注意:注入对象必须在
onPageEnd
之后才可被window
访问;复杂类型请先JSON.stringify
后传输,否则会出现「类型丢失」。
四、网页下载监听(断点续传/进度/异常)
this.ctrl.setDownloadDelegate({
onBeforeDownload: (item: webview.WebDownloadItem) => {
item.setDownloadPath('/storage/media/100/local/files/');
item.start(); // 返回 true 即继续,false 可阻断
},
onDownloadUpdated: (item) => {
console.info(`进度=${item.getPercentComplete()}%`);
},
onDownloadFailed: (item) => {
console.error(`失败=${item.getErrorCode()}`);
}
});
权限:
ohos.permission.INTERNET
+ohos.permission.WRITE_MEDIA
(官方API 18+ 已合并到WRITE_MEDIA
,不再需要WRITE_USER_STORAGE,请注意
)。
五、特殊场景答疑
多 App 同时关联同一域名
系统会弹出「选择框」;如想静默直达,可在path/pathRegex
里做区分,例如
/shop/*
→ 电商 App,/video/*
→ 短视频 App。原服务(元服务)
与普通 App 完全一致,同样走 App Linking;只是入口UIAbility
的launchType
需为singleton
。首次开机 20 min 内无法拉起
系统初次域名校验未完成,可重启或连网后等待 24 h 重试。