鸿蒙 Web 容器(三):H5 怎么「调」到 ArkTS?

鸿蒙 Web 容器(三):H5 怎么「调」到 ArkTS?

这是「ArkWeb / JSBridge」系列的第 3 篇,对应 demo 提交 3:H5按钮通过JSBridge发请求给ArkTS。

协议定好了(上一篇),现在跑这条链路的上半场:H5 里的 JS 怎么把一个请求送到原生 ArkTS 手里?

一、给 H5 装一部「内线电话」

H5 跑在 Web 内核里,原生 ArkTS 跑在应用进程里,两边本来互不相通。要让 H5 能「打电话」给 ArkTS,得有人在 H5 的 window 上装一部内线电话。

鸿蒙标准 Web 组件提供的 javaScriptProxy 就是干这个的------它把一个 ArkTS 对象注入成 H5 里的一个全局对象:

ts 复制代码
Web({ src: $rawfile('ascf_bridge_demo.html'), controller: this.controller })
  .javaScriptProxy({
    object: this.bridge,        // 要暴露的 ArkTS 对象
    name: 'ascfBridge',         // 注入到 H5 后叫 window.ascfBridge
    methodList: ['send'],       // 允许 H5 调的方法(白名单)
    controller: this.controller
  })

注册之后,H5 里就凭空多了个 window.ascfBridge,上面有个 send 方法。这就是上一篇说的「AtomicServiceEnhancedWeb 没有、标准 Web 才有」的桥原语之一 ------javaScriptProxy(另一个是回头要用的 runJavaScript)。

注意 methodList 是白名单:只有列进去的方法 H5 才调得到,没列的碰不着。这是第一道安全闸。

二、H5 这头:把请求装进信封,拿起电话

H5 点按钮时,按上一篇的 BridgeRequest 格式拼一个对象,序列化成字符串,丢进 send:

js 复制代码
function callNative(action, params) {
  var req = { id: 'req_' + Date.now() + '_' + (++seq), action: action, params: params || {} };
  if (window.ascfBridge && window.ascfBridge.send) {
    window.ascfBridge.send(JSON.stringify(req));   // ← 打电话给 ArkTS
  }
}

三个按钮分别拨 getDeviceInfo / getCurrentTime / openToast。为什么传字符串而不是对象? 因为桥两头是两套运行时,传结构化对象容易在边界上「失真」,统一序列化成 JSON 字符串最稳------所以协议里 id/action/params 全约定好,两边各自 JSON.stringify / JSON.parse。

三、ArkTS 这头:接电话、拆信封、先记一笔

被注入的那个对象 this.bridge,它的 send 方法就是「电话铃响」的地方:

ts 复制代码
export class WebBridgeChannel {
  send(jsonStr: string): void {
    const req = WebBridgeChannel.parse(jsonStr);   // 拆信封:JSON.parse → BridgeRequest
    if (req === null) { return; }                  // 非法/缺字段直接丢
    getBridgeLog().onRequest(req, jsonStr);         // 先记一笔到桥接账本
    // 提交4:按 action 分发到能力;提交5:把结果回拨给 H5
  }
}

本步到此为止 ------只「收到 + 记日志」,先不处理真实能力。页面下方那个「桥接日志 · ArkTS 收到」面板读的就是这本账本(@ObservedV2 单例),你点 H5 按钮,action / id / 原始请求 会实时蹦出来,状态先是「待处理」。这样就肉眼确认了:H5 的点击,真的送到 ArkTS 了。

四、为什么先不处理能力、只记日志?

因为这一步要单独验证「通道本身通不通」。把「通道」和「能力实现」拆开验,出问题好定位:现在如果日志能蹦出来,就说明注入、调用、序列化、接收这一串没问题;接不到,就是桥没接通------和具体能力无关。这跟之前 demo 里「先验证 WebSocket 通道、再谈业务」是同一个思路。

一句话总结

javaScriptProxy 给 H5 装了部内线电话 window.ascfBridge(methodList 是白名单),H5 把 BridgeRequest 序列化成字符串丢进 send,ArkTS 在 send 里拆包、先记一笔账。 上半场(H5 → ArkTS)就通了;下一步让 ArkTS 真去「按 action 找能力实现」。

相关推荐
福兮说5 小时前
前端下载大文件,点了按钮半天没反应:fetch + blob 的三个问题和三种替代写法
前端·javascript·性能优化·文件下载
GreenTea5 小时前
我把 Agent 的 while 循环拆掉了:一种你可能没想到的 Agent 架构
前端·后端·架构
科技观察哨6 小时前
六足平台选型与纳米定位系统集成:HEB-640六自由度位移台在半导体光刻对准中的参数边界与国产替代评估
前端·人工智能
niucloud-admin6 小时前
JAVA V6 多商户商城 开发文档——web前端
前端
颜进强6 小时前
16 · NestJS LifecycleEvents 生命周期事件:五个钩子、三条边界,和 rag-server 的优雅停机
前端·后端·ai编程
今年下半年7 小时前
【VUE】整合腾讯地图、自定义区域边界、村委名称及资产统计(放大显示资产点位)
前端·javascript·vue.js
郑州光合科技余经理8 小时前
同城电商系统:库存变更怎么同步到订单
java·开发语言·前端·后端·uni-app·php·ai编程
前端snow9 小时前
ai agent --- DeepAgents 中间件
前端
data analyse 45610 小时前
报表能自定义的国内统计工具有哪些
前端·数据分析