写点什么

HarmonyOS 5.0 应用开发——Web 组件的使用

作者:高心星
  • 2024-12-03
    江苏
  • 本文字数:3573 字

    阅读完需:约 12 分钟

HarmonyOS 5.0应用开发——Web组件的使用

【高心星出品】


Web 组件的使用

ArkWeb(方舟 Web)提供了 Web 组件,用于在应用程序中显示 Web 页面内容。常见使用场景包括:


  • 应用集成 Web 页面:应用可以在页面中使用 Web 组件,嵌入 Web 页面内容,以降低开发成本,提升开发、运营效率。

  • 浏览器网页浏览场景:浏览器类应用可以使用 Web 组件,打开三方网页,使用无痕模式浏览 Web 页面,设置广告拦截等。

  • 小程序:小程序类宿主应用可以使用 Web 组件,渲染小程序的页面。

加载网页资源

private webcontroller:WebviewController=new webview.WebviewController()//控制器....Web({src:'https://www.sohu.com/',controller:this.webcontroller})  .margin(20)
复制代码



这里的 src 可以提供网络地址,也可以提供项目中本地网页代码资源。

项目结构


项目代码
import { webview } from '@kit.ArkWeb';
@Entry@Componentstruct Index { @State message: string = 'Hello World'; private webcontroller:WebviewController=new webview.WebviewController() build() { Column(){ Button('重新加载') .onClick(()=>{ //重新加载本地资源 this.webcontroller.loadUrl($rawfile('test.html')) }) //加载网络地址 Web({src:'https://www.sohu.com/',controller:this.webcontroller}) .margin(20) } .width('100%') .height('100%') }}
复制代码



Web 组件的生命周期方法

Web 组件提供了丰富的组件生命周期回调接口,通过这些回调接口,开发者可以感知 Web 组件的生命周期状态变化,进行相关的业务处理。


Web 组件的状态主要包括:Controller 绑定到 Web 组件、网页加载开始、网页加载进度、网页加载结束、页面即将可见等。



  • onControllerAttached 事件:当 Controller 成功绑定到 Web 组件时触发该回调,且禁止在该事件回调前调用 Web 组件相关的接口,否则会抛出 js-error 异常。推荐在此事件中注入 JS 对象 registerJavaScriptProxy、设置自定义用户代理 setCustomUserAgent,可以在回调中使用 loadUrl,getWebId 等操作网页不相关的接口。但因该回调调用时网页还未加载,因此无法在回调中使用有关操作网页的接口,例如 zoomIn、zoomOut 等。

  • onLoadIntercept 事件:当 Web 组件加载 url 之前触发该回调,用于判断是否阻止此次访问。默认允许加载。

  • onOverrideUrlLoading 事件:当 URL 将要加载到当前 Web 中时,让宿主应用程序有机会获得控制权,回调函数返回 true 将导致当前 Web 中止加载 URL,而返回 false 则会导致 Web 继续照常加载 URL。onLoadIntercept 接口和 onOverrideUrlLoading 接口行为不一致,触发时机也不同,所以在应用场景上存在一定区别。主要是在 LoadUrl 和 iframe(HTML 标签,表示 HTML 内联框架元素,用于将另一个页面嵌入到当前页面中)加载时,onLoadIntercept 事件会正常回调到,但 onOverrideUrlLoading 事件在 LoadUrl 加载时不会触发,在 iframe 加载 HTTP(s)协议或 about:blank 时也不会触发。详细介绍请见 onLoadIntercept 和 onOverrideUrlLoading 的说明。

  • onInterceptRequest 事件:当 Web 组件加载 url 之前触发该回调,用于拦截 url 并返回响应数据。

  • onPageBegin 事件:网页开始加载时触发该回调,且只在主 frame(表示一个 HTML 元素,用于展示 HTML 页面的 HTML 元素)触发。如果是 iframe 或者 frameset(用于包含 frame 的 HTML 标签)的内容加载时则不会触发此回调。多 frame 页面有可能同时开始加载,即使主 frame 已经加载结束,子 frame 也有可能才开始或者继续加载中。同一页面导航(片段、历史状态等)或者在提交前失败、被取消的导航等也不会触发该回调。

  • onProgressChange 事件:告知开发者当前页面加载的进度。多 frame 页面或者子 frame 有可能还在继续加载而主 frame 可能已经加载结束,所以在 onPageEnd 事件后依然有可能收到该事件。

  • onPageEnd 事件:网页加载完成时触发该回调,且只在主 frame 触发。多 frame 页面有可能同时开始加载,即使主 frame 已经加载结束,子 frame 也有可能才开始或者继续加载中。同一页面导航(片段、历史状态等)或者在提交前失败、被取消的导航等也不会触发该回调。推荐在此回调中执行 JavaScript 脚本 loadUrl 等。需要注意的是收到该回调并不能保证 Web 绘制的下一帧将反映此时 DOM 的状态。

  • onPageVisible 事件:Web 回调事件。渲染流程中当 HTTP 响应的主体开始加载,新页面即将可见时触发该回调。此时文档加载还处于早期,因此链接的资源比如在线 CSS、在线图片等可能尚不可用。

  • onRenderExited 事件:应用渲染进程异常退出时触发该回调,可以在此回调中进行系统资源的释放、数据的保存等操作。如果应用希望异常恢复,需要调用 loadUrl 接口重新加载页面。

  • onDisAppear 事件:组件卸载消失时触发此回调。该事件为通用事件,指组件从组件树上卸载时触发的事件。

项目结构


import { webview } from '@kit.ArkWeb';import { buffer } from '@kit.ArkTS';
@Entry@Componentstruct Index { @State message: string = 'Hello World'; private webcontroller: WebviewController = new webview.WebviewController()
build() { Column() { Button('重新加载') .onClick(() => { this.webcontroller.loadUrl($rawfile('test.html')) }) Web({ src: 'https://www.sohu.com/', controller: this.webcontroller }) .onControllerAttached(() => { //此时controller可以使用,一番设置或者注入js对象 console.log('gxxt ', 'controller绑定web的时候调用') }) .onLoadIntercept((event) => { // 获取请求地址 请求方法 console.log('gxxt ', '即将加载俩 url= ' + event.data.getRequestUrl()) // 返回true则拦截此次请求,false表示不拦截 return false }) .onInterceptRequest((event) => { console.log('gxxt 根据url 即将发起请求: ' + event.request.getRequestUrl()) // 如果请求地址有https if (event.request.getRequestUrl().indexOf('https') >= 0) { //自己定义一个响应 let webreqres = new WebResourceResponse() webreqres.setResponseEncoding('UTF-8') webreqres.setResponseMimeType('text/html') webreqres.setResponseCode(200) webreqres.setResponseData(this.getrawstr()) return webreqres } // 否则 继续返回 return null }) .onPageBegin((event) => { //页面开始加载的时候调用 console.log('gxxt 页面开始加载:' + event.url) }) .onProgressChange((event) => { console.log('gxxt 加载进度: ' + event.newProgress) }) .onPageEnd((event) => { console.log('gxxt 页面加载完毕: ' + event.url) }) .margin(20) } .width('100%') .height('100%') }
getrawstr() { //读取网页内容转换成字符串 let buffer1 = getContext(this).resourceManager.getRawFileContentSync('intercept.html').buffer return buffer.from(buffer1).toString() }}
复制代码



网页导航

在前端页面点击网页中的链接时,Web 组件默认会自动打开并加载目标网址。当前端页面替换为新的加载链接时,会自动记录已经访问的网页地址。可以通过 forward()和 backward()接口向前/向后浏览上一个/下一个历史记录。


例如点击后退键的时候,我们不再推出应用而是回到上一页,如果没有上一页再退出应用。



import { webview } from '@kit.ArkWeb';import { buffer } from '@kit.ArkTS';
@Entry@Componentstruct Index { @State message: string = 'Hello World'; private webcontroller: WebviewController = new webview.WebviewController()
build() { Column() { Button('重新加载') .onClick(() => { this.webcontroller.loadUrl($rawfile('test.html')) }) Web({ src: 'https://www.sohu.com/', controller: this.webcontroller }) .margin(20) } .width('100%') .height('100%') }
// getrawstr() { // let buffer1 = getContext(this).resourceManager.getRawFileContentSync('intercept.html').buffer // return buffer.from(buffer1).toString() // } onBackPress(): boolean | void { // 如果能后退就退到上一页 if(this.webcontroller.accessBackward()) { this.webcontroller.backward() // 拦截默认的back键操作 return true
}else{ // 否则不拦截 return false } }}
复制代码


用户头像

高心星

关注

天将降大任于斯人也,必先苦其心志。 2024-10-17 加入

华为开发者专家(HDE)。 10年教学经验,兼任多家科技公司技术顾问。先后从事JavaEE项目开发、Python爬虫、HarmonyOS移动应用开发等课程的教学工作。参与开发《鸿蒙应用开发基础》和《鸿蒙项目实战》等课程。

评论

发布
暂无评论
HarmonyOS 5.0应用开发——Web组件的使用_鸿蒙Next_高心星_InfoQ写作社区