news 2026/8/7 12:14:30

HarmonyOS7 原生和网页怎么互调:WebJavaScriptBridge 双向通信入门

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS7 原生和网页怎么互调:WebJavaScriptBridge 双向通信入门

文章目录

      • 前言
      • 案例的结构重点
      • 完整代码
      • 先把两条调用方向讲透
        • 方向一:ArkUI 调 JavaScript
        • 方向二:JavaScript 调 ArkUI
      • `jsResult` 这个状态为什么要留着
      • 双向通信流程可以怎么理解
      • 关键代码怎么迁移到真实业务
      • 安全提醒不是装饰
      • 这个案例适合的真实场景
      • 常见坑我提前说几个
      • 写在最后

前言

一旦Web组件不只是拿来“展示网页”,事情就开始复杂了。活动页想调用原生分享,H5 想拿登录态,原生按钮想通知网页切 tab,最后都会落到一个词上:桥接。

这个话题一上来就讲实现细节,往往很容易把人讲懵。因为桥接不是一个 API,而是一套通信关系。案例这一页的价值就在这,它没有急着写满接口,而是先把 ArkUI 和网页之间的调用方向讲清楚。

说白了,你得先知道谁调用谁,再谈怎么调用。

案例的结构重点

案例把桥接拆成了三部分:

  • ArkUI 调 JavaScript
  • JavaScript 调 ArkUI
  • 双向通信的完整流程

同时,它还放了一个最小状态jsResult,用来观察交互后的结果变化。这个思路是对的,因为桥接这种东西,如果没有一个状态出口,很难确认链路到底通没通。

完整代码

import{DEMO_BG_COLOR,DEMO_CARD_COLOR,DEMO_THEME_COLOR,DEMO_SUBTEXT_COLOR}from'./types'@Entry@Componentstruct WebJavaScriptBridge{@StateisShow:boolean=true@StatejsResult:string='等待调用...'callJsDemo():void{this.jsResult=`JS 调用结果:${Date.now()}`}build(){Column(){if(this.isShow){Scroll(){Column({space:16}){Text('Web JavaScript 交互').fontSize(16).fontColor(DEMO_THEME_COLOR).fontWeight(FontWeight.Bold)Column(){Text('JS Bridge 交互模式').fontSize(13).fontColor('#4D96FF').margin({bottom:10})Column({space:12}){Column(){Text('方向一: ArkUI -> JS').fontSize(12).fontColor('#4D96FF').fontWeight(FontWeight.Bold)Column(){Text('controller.runJavaScript(code)').fontSize(11).fontColor('#FFFFFF')}.width('100%').height(40).backgroundColor('#4D96FF').borderRadius(6).justifyContent(FlexAlign.Center)}Column(){Text('方向二: JS -> ArkUI').fontSize(12).fontColor('#FFA500').fontWeight(FontWeight.Bold)Column(){Text('.onControllerAttached() 注册 JS 回调').fontSize(11).fontColor('#FFFFFF')}.width('100%').height(40).backgroundColor('#FFA500').borderRadius(6).justifyContent(FlexAlign.Center)}Column(){Text('双向通信流程').fontSize(12).fontColor('#6BCB77').fontWeight(FontWeight.Bold)Column({space:4}){Text('1. ArkUI 调用 runJavaScript() 执行 JS').fontSize(10).fontColor('#FFFFFFCC')Text('2. JS 通过 window.ohosCallNative() 回调').fontSize(10).fontColor('#FFFFFFCC')Text('3. 注册 javaScriptProxy 实现双向调用').fontSize(10).fontColor('#FFFFFFCC')}.width('100%').backgroundColor('#6BCB77').borderRadius(6).padding(8)}}}.backgroundColor(DEMO_CARD_COLOR).padding(12).borderRadius(12)Column({space:8}){Text('交互结果展示').fontSize(14).fontColor(DEMO_THEME_COLOR).fontWeight(FontWeight.Bold)Text(this.jsResult).fontSize(13).fontColor('#1A1A1A')Button('模拟 JS 调用').onClick(()=>{this.callJsDemo()}).fontSize(12).backgroundColor(DEMO_THEME_COLOR)Button('模拟 runJavaScript').onClick(()=>{this.jsResult='执行 JS: changeTitle("New Title")'}).fontSize(12).backgroundColor('#6BCB77')}.backgroundColor('#E8F4FD').padding(14).borderRadius(12)Column({space:4}){Text('安全注意事项').fontSize(13).fontColor('#FF6B6B')Text('使用 javaScriptProxy 时注意安全').fontSize(12).fontColor('#333333')Text('避免注入恶意代码和 XSS 攻击').fontSize(12).fontColor('#333333')Text('验证所有 JS 回调的数据合法性').fontSize(12).fontColor('#333333')}.width('100%').backgroundColor('#FFF0F0').padding(12).borderRadius(8)}.width('100%')}}Text('WebJavaScriptBridge - JS Bridge 通信').fontSize(12).fontColor(DEMO_SUBTEXT_COLOR).margin({top:12})}.width('100%').height('100%').backgroundColor(DEMO_BG_COLOR).padding(16)}}

先把两条调用方向讲透

这部分是整篇最重要的认知点。

方向一:ArkUI 调 JavaScript

这是最容易理解的一条链路。原生侧通过控制器执行网页里的 JS 代码:

controller.runJavaScript(code)

比如网页里有个changeTitle(),那原生按钮就可以主动触发它。这个能力特别适合什么场景?

很典型的一类,是原生操作区控制网页内容。比如原生头部点“切换主题”“打开弹层”“跳到某个 section”,页面主体其实是 H5,这时候就要用原生去调 JS。

方向二:JavaScript 调 ArkUI

反过来,网页也可能需要告诉原生侧一些事情。比如:

  • H5 登录完成,通知原生刷新用户信息
  • 点击网页里的分享按钮,唤起原生分享面板
  • H5 页面里的某个链接不是普通跳转,而是触发原生路由

案例里用这句描述得比较抽象:

.onControllerAttached()注册JS回调

真实项目里,核心思想就是把一个可调用的原生接口暴露给网页脚本。网页拿到之后,就能带着参数回调原生。

jsResult这个状态为什么要留着

案例用@State jsResult保存交互结果:

@StatejsResult:string='等待调用...'

然后在点击按钮后更新它:

callJsDemo():void{this.jsResult=`JS 调用结果:${Date.now()}`}

这不是为了做花活,而是为了让桥接变得可观测。

桥接出问题时,最麻烦的是你经常不知道卡在哪一段。是按钮没点到?是原生方法没执行?还是网页没回传?只要你在页面里保留一个明确的结果显示区,调试效率会高很多。

双向通信流程可以怎么理解

案例把完整流程总结成三步:

1.ArkUI 调用runJavaScript()执行JS2.JS通过 window.ohosCallNative()回调3.注册 javaScriptProxy 实现双向调用

这三句本质上讲的是一件事:原生和网页都不能把对方当成本地函数直接调用,中间需要一个约定好的桥。

你可以把它理解成一套跨边界协议。

原生发消息过去,网页按约定的方法名和参数处理;网页再回消息回来,原生按同样约定接住。真正麻烦的不是调用本身,而是调用协议是否稳定。

关键代码怎么迁移到真实业务

如果你要落地到项目里,建议最开始只定义少量桥接动作,不要一口气开放十几个接口。

一个靠谱的做法是:

  • 先约定统一的数据格式,比如{ action, payload }
  • 让原生只暴露少数可控动作,比如分享、登录态获取、页面关闭
  • 对所有来自网页的数据做校验,不要直接信任

桥接的核心不是“能调通”,而是“可控、可维护、可排查”。这点很重要。

安全提醒不是装饰

案例最后专门给了安全区,这一点非常对。

Text('使用 javaScriptProxy 时注意安全')Text('避免注入恶意代码和 XSS 攻击')Text('验证所有 JS 回调的数据合法性')

很多人做桥接只关注功能,结果把网页当成绝对可信。只要外部内容来源稍微复杂一点,这种思路就会出事。

至少要守住三条底线:

第一,不要执行未经约束的任意脚本。

第二,不要把敏感能力全部开放给网页。

第三,所有回调参数都要校验格式和内容,不能拿来就用。

这个案例适合的真实场景

活动页分享、H5 支付结果通知、内容页唤起原生评论区、嵌入式管理后台、Hybrid 登录流,这些都是桥接高频场景。

尤其当你项目里一部分页面是网页、一部分页面是原生时,桥接能力几乎绕不过去。区别只在于你是先把它设计清楚,还是后面边补边救火。

常见坑我提前说几个

第一个坑,是直接把方法名和参数写死在多个页面里。后面一改协议,所有地方一起炸。

第二个坑,是桥接动作没有日志。调试时只看到“没反应”,但不知道消息有没有发出去。

第三个坑,是把桥接当成万能方案。很多高频交互如果可以原生化,长期看还是原生更稳。

第四个坑,是没有设计调用失败的兜底。网页调原生失败、原生调网页失败,都应该有明确反馈。

写在最后

桥接这件事,最怕的不是复杂,而是含糊。只要你先把方向分清楚,再把协议和安全边界收紧,它其实就是一套可以逐步扩展的通信层。

这个案例最适合拿来当认知起点。你不一定今天就把完整桥接写完,但至少从现在开始,原生和网页之间那条线不会再是一团雾了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/7 12:11:57

揭秘外贸主动营销网站建设:从被动等待到主动出击的全链路转化指南

在这个快节奏的数字商业时代,许多老板和业务老总在谈起外贸时,第一反应往往是“我在上面发了产品”,然后就是日复一日的等待。等待询盘,等待回复,等待客户的青睐。然而现实是残酷的,发出去的产品像石沉大海,好不容易收到的询盘又是层层比价,最后被低价抢走。这种“守株…

作者头像 李华
网站建设 2026/8/7 12:10:34

【关注可白嫖源码】--课程设计--毕业设计--springboot校园新闻发布系统[编号:project81008](案件分析)

本文仅展示核心实现逻辑与部分代码片段,完整项目源码、配套文档、数据库脚本内容较多,篇幅有限无法全部放出。 有需要完整资源的同学,可以在评论区留言【资料或领源码】,我会一 一回复站内私信,发送完整文件 摘 要 校…

作者头像 李华
网站建设 2026/8/7 12:08:24

Allegro PCB Contour模式:高效实现板边等距走线

1. 项目概述:为什么需要沿着板子轮廓走线? 在Allegro PCB Editor里画板子,你有没有遇到过这种情况:板子外形是个不规则的圆弧或者异形,你需要沿着这个边缘走一根电源线或者地线,结果手动一根根线段去描&…

作者头像 李华
网站建设 2026/8/7 12:08:09

从PC到Mac:OpenCore黑苹果实战指南

从PC到Mac:OpenCore黑苹果实战指南 【免费下载链接】Hackintosh 国光的黑苹果安装教程:手把手教你配置 OpenCore 项目地址: https://gitcode.com/gh_mirrors/hac/Hackintosh 想要在普通PC上体验macOS的优雅与高效?国光的黑苹果安装教程…

作者头像 李华
网站建设 2026/8/7 12:08:01

5大核心功能:跨平台GUI智能代理Mobile-Agent完全指南

5大核心功能:跨平台GUI智能代理Mobile-Agent完全指南 【免费下载链接】MobileAgent Mobile-Agent: The Powerful GUI Agent Family 项目地址: https://gitcode.com/GitHub_Trending/mo/MobileAgent 你是否曾经幻想过,只需要用自然语言告诉AI&quo…

作者头像 李华
网站建设 2026/8/7 12:07:50

UniApp视频播放开发全攻略:从基础组件到原生插件避坑实践

1. 从零到一:为什么你的UniApp视频播放总是不如意? 做移动端开发,尤其是跨平台开发,视频播放功能绝对是个高频需求,也是个高频“雷区”。无论是电商的商品展示、教育的学习课程,还是社交的短视频分享&#…

作者头像 李华