免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

ArkWeb手记02|HarmonyOS7 拦截H5跳转与自定义路由接管

ArkWeb手记02|HarmonyOS7 拦截H5跳转与自定义路由接管 适配HarmonyOS7API26连载02/10开篇H5跳转不受控是混合开发第二大坑做鸿蒙ArkWeb混合应用写完基础页面加载和生命周期之后下一个一定会撞上的问题H5里面点链接直接在当前Web页面跳转。想拦截某些链接跳转到鸿蒙原生页面或者禁止打开外部网页、拦截弹窗新窗口默认行为根本做不到。我之前接手一个项目H5里面埋了外链。用户一点直接跳外部网页回退逻辑混乱还有H5里window.open()打开新页面直接失效要么白屏要么直接在当前页面覆盖产品提了一堆bug。很多新手以为H5的跳转只能交给前端控制。其实不是HarmonyOS7的ArkWeb提供了跳转拦截回调我们可以在原生层接管所有URL跳转请求决定放行、拦截甚至切到鸿蒙原生页面。这篇手记我们就解决路由接管这件事。学会拦截链接、区分内部H5路由和外部链接处理H5新窗口打开场景统一混合应用路由逻辑。本篇目标理解ArkWeb的onUrlIntercept拦截回调触发时机区分点击跳转、js跳转、window.open三种不同跳转事件编写规则放行内部业务链接拦截外部域名H5 window.open新窗口劫持用原生页面承载新Web实例搭建简易路由管理器H5链接一键跳转原生ArkUI页面一、基础概念ArkWeb跳转拦截到底拦截什么先分清一件事H5页面跳转分两类。一类是用户点击a标签触发页面跳转另一类是JS代码执行location.href、window.open触发跳转。在HarmonyOS7里所有这类请求都会经过onUrlIntercept回调。这个回调在页面发起请求之前触发我们有机会直接决定要不要放行。一句话类比onUrlIntercept就像收费站。H5发起跳转请求先到收费站由原生代码判断允许通行就继续加载网页直接拦下执行我们自定义逻辑。常见误区❌ 拦截回调只拦截a标签点击JS跳转拦不住✅ onUrlIntercept可以拦截绝大多数跳转但是window.open属于单独事件需要额外监听onNewWindowHarmonyOS7路由拦截时序H5触发跳转点击链接 / JS修改location.href触发 onUrlIntercept拿到目标URL执行我们写的匹配规则返回true拦截不再加载这个网页返回false放行ArkWeb正常加载目标页面划重点返回值千万别搞反。很多人写反导致页面点任何链接都被直接拦截页面卡死。API26文档这点描述很容易看错踩坑的人特别多。二、最简代码实现URL拦截内外域名区分先写基础拦截代码给ArkWeb组件绑定onUrlIntercept。我们做一个简单规则本业务域名放行外部第三方域名直接拦截弹出提示。import{Web,WebController,WebResourceError,WebUrlInterceptResult}fromkit.ArkWeb;EntryComponentstruct ArkWebRoutePage{privatewebController:WebControllernewWebController();StatetipMsg:string;// 业务允许的H5域名白名单privateallowHostList:string[][xxx-business.com];aboutToAppear(){this.webController.setJavaScriptEnabled(true);this.webController.setDomStorageEnabled(true);}build(){Column(){if(this.tipMsg.length0){Text(this.tipMsg).fontSize(16).fontColor(Color.Orange).margin(12)}Web({src:https://xxx-business.com/index.html,controller:this.webController}).onUrlIntercept((url:string){console.info(捕获跳转URL,url);consturlObjnewURL(url);consthosturlObj.hostname;// 判断是否在白名单constisAllowthis.allowHostList.some(itemhost.includes(item));if(!isAllow){this.tipMsg外部链接已拦截;// 返回true 拦截本次跳转returnWebUrlInterceptResult.INTERCEPT;}// 返回false 放行正常加载H5页面returnWebUrlInterceptResult.ALLOW;}).width(100%).layoutWeight(1)}}aboutToDisappear(){this.webController.stop();this.webController.destroy();}}代码逐段解释onUrlIntercept((url:string){...})跳转拦截回调每次跳转都会把目标 URL 丢进来。new URL (url)解析域名、路径方便做白名单匹配。注意非法 URL 会抛出异常生产环境需要加 try-catch。WebUrlInterceptResult.INTERCEPT拦截跳转不再加载页面WebUrlInterceptResult.ALLOW放行。老版本教程会直接 return true/falseHarmonyOS7 API26 推荐使用枚举常量可读性更强。踩坑提醒如果 H5 页面是本地 rawfile 静态页面跳转的相对路径也会进入这个拦截回调写匹配规则的时候要考虑相对路径场景不要直接报错。三、进阶场景H5 window.open 新窗口打开处理H5 页面经常有window.open(xxx.html)用来弹出新页面。默认情况下ArkWeb 不会自动新建页面这个事件会触发onNewWindow回调。onUrlIntercept 拦不住 window.open很多人在这里卡很久。我们绑定 onNewWindow 回调当 H5 调用 window.open 的时候由原生创建新 WebController打开新的鸿蒙页面。.onNewWindow((url:string) { console.info(H5请求打开新窗口地址, url); // 这里可以调用路由打开新页面传入目标url // router.pushUrl打开新的ArkUI页面新页面里面挂载独立Web组件 return true; })返回 true 代表我们原生接管新窗口返回 false代表不支持新窗口H5 的 window.open 直接失效。这里要注意每一个新窗口都需要独立的 WebController 实例。不要复用当前页面的 controller复用会导致两个页面互相抢占内核出现渲染错乱。四、混合路由H5 链接直接跳转鸿蒙原生页面这是混合开发非常实用的能力。约定一套自定义协议比如harmony://native/pageDetail。H5 点击链接触发 onUrlIntercept识别这个自定义协议直接拦截调用鸿蒙原生路由打开原生页面不加载任何网页。修改拦截回调内部逻辑.onUrlIntercept((url:string){console.info(捕获跳转URL,url);// 匹配自定义原生协议if(url.startsWith(harmony://native/)){// 拦截打开原生页面router.pushUrl({url:url});returnWebUrlInterceptResult.INTERCEPT;}consturlObjnewURL(url);consthosturlObj.hostname;constisAllowthis.allowHostList.some(itemhost.includes(item));if(!isAllow){this.tipMsg外部链接已拦截;returnWebUrlInterceptResult.INTERCEPT;}returnWebUrlInterceptResult.ALLOW;})注意需要导入 router 模块import router from ohos.router;这种方案可以做到 H5 和原生路由统一管理。H5 不用关心原生页面怎么实现只需要跳转约定协议链接。五、异常兜底URL 解析容错防止页面崩溃如果 H5 传了畸形、非法 URLnew URL(url)会直接抛出异常整个页面直接崩溃。生产环境必须包一层 try catch。.onUrlIntercept((url:string){try{console.info(捕获跳转URL,url);if(url.startsWith(harmony://native/)){router.pushUrl({url:url});returnWebUrlInterceptResult.INTERCEPT;}consturlObjnewURL(url);consthosturlObj.hostname;constisAllowthis.allowHostList.some(itemhost.includes(item));if(!isAllow){this.tipMsg外部链接已拦截;returnWebUrlInterceptResult.INTERCEPT;}returnWebUrlInterceptResult.ALLOW;}catch(err){console.error(URL解析失败,err);returnWebUrlInterceptResult.INTERCEPT;}})六、真机调试路由日志查看模拟器测试跳转拦截逻辑最好打开日志窗口。每次跳转url 都会打印到控制台。测试流程H5 页面添加 a 标签分别写内部业务链接、外部链接、自定义 native 协议链接逐个点击观察日志检查内部链接正常打开外部链接拦截native 协议跳转原生页面小坑部分 H5 框架路由是前端 hash 路由# 后面的内容不会触发页面刷新onUrlIntercept 不会触发。hash 路由属于前端内部状态变更不会发起页面跳转请求这点一定要分清。七、本篇总结 课后练习任务知识点汇总onUrlIntercept 在跳转发起前拦截请求可以放行或者阻断网页加载返回枚举不要写反。window.open 不会触发 onUrlIntercept需要单独监听 onNewWindow 回调新建独立 Web 实例。自定义协议可以打通 H5 到原生页面跳转实现混合应用路由统一。URL 解析一定要增加 try-catch畸形 URL 会直接造成页面崩溃。hash 模式前端路由不会触发页面跳转拦截这是前端路由本身的特性。实践任务为下一期做铺垫基于本篇代码自行实现两点增加拦截黑名单域名列表匹配关键词直接阻断监听页面回退事件控制 Web 页面的 goBack 逻辑和鸿蒙系统返回按键联动。下一期手记 03我们讲 ArkWeb 返回按键、历史栈管理处理 H5 页面回退与原生页面回退冲突问题。
返回列表