当前位置: 首页 > news >正文

ArkTS开发系列之Web组件的学习(2.9)

上篇回顾:ArkTS开发系列之事件(2.8.2手势事件)

本篇内容: ArkTS开发系列之Web组件的学习(2.9)

一、知识储备

Web组件就是用来展示网页的一个组件。具有页面加载、页面交互以及页面调试功能

1. 加载网络页面

      Web({ src: this.indexUrl, controller: this.webViewController })

2. 加载本地页面

      Web({ src: $rawfile('local.html'), controller: this.webViewController })

3. 加载html格式的文本数据

  • 该示例中,是点击button后开始加载html格式的文本数据
      Button('加载html文本内容').onClick(event => {this.webViewController.loadData("<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>","text/html","UTF-8");})Web({ src: this.indexUrl, controller: this.webViewController })

4.深色模式设置

      Web({ src: this.indexUrl, controller: this.webViewController }).darkMode(WebDarkMode.On) //设置深色模式.forceDarkAccess(true)//强制生效

5. 文件上传

      Web({ src: $rawfile('local.html'), controller: this.webViewController }).onShowFileSelector(event=>{//设置要上传的文件路径let fileList: Array<string> =[]if (event) {event.result.handleFileList(fileList)}return true;})

6. 在新容器中打开页面

  • 通过multiWindowAccess()来设置是否允许网页在新窗口中打开。有新窗口打开时,应用侧会在onWindowNew()接口中收到新窗口事件,需要我们在此接口中处理web组件的窗口请求
.onWindowNew(event=>{
}
  • 如果开发者在onWindowNew()接口通知中不需要打开新窗口,需要将ControllerHandler.setWebController()接口返回值设置成null。

7. 管理位置权限

        .geolocationAccess(true)

8. 应用调用html的js函数

      Web({ src: $rawfile('local.html'), controller: this.webViewController }).javaScriptAccess(true)
this.webViewController.runJavaScript('htmlTest()')

9. 前端调用应用函数

  • 在web组件初始化的时候注入javaScriptProxy()
  @State testObj: TestClass = new TestClass(); //注册应用内js调用函数的对象Web({ src: $rawfile('local.html'), controller: this.webViewController }).javaScriptProxy({//将对角注入到web端object: this.testObj,name: 'testObjName',methodList: ['test'],controller: this.webViewController})
  • 在web组件初始化完成后注入registerJavaScriptProxy()
 this.webviewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test", "toString"]);

10. 应用与前端页面数据通道

  aboutToAppear() {try {//1.在这里初始化portsthis.ports = this.webViewController.createWebMessagePorts();this.ports[1].onMessageEvent((result: webview.WebMessage) => { //2.接收消息,并根据业务处理消息let msg = '读取网页消息'if (typeof (result) == 'string') {msg = msg + result;} else if (typeof (result) == 'object') {if (result instanceof ArrayBuffer) {msg = msg + " result length: " + result.byteLength;} else {console.error('msg not support')}} else {console.error('msg not support')}this.receiveMsgFromHtml = msg;// 3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。this.webViewController.postMessage('__init_port__', [this.ports[0]], "*");})} catch (err) {console.error('err: ' + JSON.stringify(err))}}//4.给html发消息this.ports[1].postMessageEvent(this.sendFromEts)

11. 管理web组件的页面跳转和浏览记录

  • 返回上一页
          this.controller.backward()
  • 进入下一页
          this.controller.forward()
  • 从web组件跳转到hap应用内的页面
      Web({ controller: this.controller, src: $rawfile('route.html') }).onUrlLoadIntercept(event => {let url: string = event.data as string;if (url.indexOf('native://') === 0) {router.pushUrl({ url: url.substring(9) })return true;}return false;})
  • 跨应用的页面跳转
            call.makeCall(url.substring(6), err => {if (!err) {console.info('打电话成功')} else {console.info('拨号失败' + JSON.stringify(err))}})

12. 管理Cookie及数据存储

Cookie信息保存在应用沙箱路径下/proc/{pid}/root/data/storage/el2/base/cache/web/Cookiesd的文件中。
由WebCookieManager管理cookie

      webview.WebCookieManager.setCookie('https://www.baidu.com','val=yes') //存储cookie
  • 四种缓存策略(Cache)
    Default : 优先使用未过期的缓存,如果缓存不存在,则从网络获取。
    None : 加载资源使用cache,如果cache中无该资源则从网络中获取。
    Online : 加载资源不使用cache,全部从网络中获取。
    Only :只从cache中加载资源。
  • 清除缓存
this.controller.removeCache(true);
  • 是否持久化缓存domStorageAccess
domStorageAccess(true) ///true是Local Storage持久化存储;false是Session Storage,会随会话生命周期释放

13. 自定义页面请求响应

通过对onIntercerptRequest接口来实现自定义

        .onInterceptRequest((event?: Record<string, WebResourceRequest>): WebResourceResponse => {if (!event) {return new WebResourceResponse();}let mRequest: WebResourceRequest = event.request as WebResourceRequest;console.info('url: ' + mRequest.getRequestUrl())if (mRequest.getRequestUrl().indexOf('https://www.baidu.com') === 0) {this.responseResource.setResponseData(this.webdata)this.responseResource.setResponseEncoding('utf-8')this.responseResource.setResponseMimeType('text/html')this.responseResource.setResponseCode(200);this.responseResource.setReasonMessage('OK')return this.responseResource;}return;})

14.

  • 第一步
  aboutToAppear() {// 配置web开启调试模式web_webview.WebviewController.setWebDebuggingAccess(true);}
  • 第二步
// 添加映射 
hdc fport tcp:9222 tcp:9222 
// 查看映射 
hdc fport ls
  • 第三步
在电脑端chrome浏览器地址栏中输入chrome://inspect/#devices,页面识别到设备后,就可以开始页面调试。

二、 效果一览

在这里插入图片描述

三、 源码大杂烩

import webview from '@ohos.web.webview'
import router from '@ohos.router';
import call from '@ohos.telephony.call';@Entry
@Component
struct Index {controller: webview.WebviewController = new webview.WebviewController();responseResource: WebResourceResponse = new WebResourceResponse();@State webdata: string = "<!DOCTYPE html>\n" +"<html>\n" +"<head>\n" +"<title>将www.baidu.com改成我</title>\n" +"</head>\n" +"<body>\n" +"<h1>将www.baidu.com改成我</h1>\n" +"</body>\n" +"</html>"build() {Column() {Button('上一页').onClick(() => {this.controller.backward()})Button('下一页').onClick(() => {this.controller.forward()})Web({ controller: this.controller, src: 'www.baidu.com' })// Web({ controller: this.controller, src: $rawfile('route.html') }).onUrlLoadIntercept(event => {let url: string = event.data as string;if (url.indexOf('native://') === 0) {router.pushUrl({ url: url.substring(9) })return true;} else if (url.indexOf('tel://') === 0) {call.makeCall(url.substring(6), err => {if (!err) {console.info('打电话成功')} else {console.info('拨号失败' + JSON.stringify(err))}})return true;}return false;}).onInterceptRequest((event?: Record<string, WebResourceRequest>): WebResourceResponse => {if (!event) {return new WebResourceResponse();}let mRequest: WebResourceRequest = event.request as WebResourceRequest;console.info('url: ' + mRequest.getRequestUrl())if (mRequest.getRequestUrl().indexOf('https://www.baidu.com') === 0) {this.responseResource.setResponseData(this.webdata)this.responseResource.setResponseEncoding('utf-8')this.responseResource.setResponseMimeType('text/html')this.responseResource.setResponseCode(200);this.responseResource.setReasonMessage('OK')return this.responseResource;}return;})// webview.WebCookieManager.setCookie('https://www.baidu.com','val=yes')}.width('100%').height('100%')}
}
import webview from '@ohos.web.webview';
import common from '@ohos.app.ability.common';
import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
import geoLocationManager from '@ohos.geoLocationManager';let context = getContext(this) as common.UIAbilityContext;
let atManager = abilityAccessCtrl.createAtManager();
try {atManager.requestPermissionsFromUser(context, ["ohos.permission.LOCATION", "ohos.permission.APPROXIMATELY_LOCATION"], (err, data) => {// let requestInfo: geoLocationManager.LocationRequest = {//   'priority': 0x203,//   'scenario': 0x300,//   'maxAccuracy': 0// };//// let locationChange = (location: geoLocationManager.Location): void => {//   if (location) {//     console.error('location = ' + JSON.stringify(location))//   }// };//// try {//   geoLocationManager.on('locationChange', requestInfo, locationChange);//   geoLocationManager.off('locationChange', locationChange);// } catch (err) {//   console.error('err : ' + JSON.stringify(err))// }console.info('data: ' + JSON.stringify(data))console.info("data permissions: " + JSON.stringify(data.permissions))console.info("data authResults: " + JSON.stringify(data.authResults))})
} catch (err) {console.error('err : ', err)
}class TestClass {constructor() {}test() {return '我是应用内函数';}
}@Entry
@Component
struct Index {@State indexUrl: string = 'www.baidu.com';webViewController: webview.WebviewController = new webview.WebviewController();dialog: CustomDialogController | null = null@State testObj: TestClass = new TestClass(); //注册应用内js调用函数的对象ports: webview.WebMessagePort[]; //消息端口@State sendFromEts: string = '这消息将被发送到html'@State receiveMsgFromHtml: string = '这将展示接收到html发来的消息'aboutToAppear() {try {//1.在这里初始化portsthis.ports = this.webViewController.createWebMessagePorts();this.ports[1].onMessageEvent((result: webview.WebMessage) => { //2.接收消息,并根据业务处理消息let msg = '读取网页消息'if (typeof (result) == 'string') {msg = msg + result;} else if (typeof (result) == 'object') {if (result instanceof ArrayBuffer) {msg = msg + " result length: " + result.byteLength;} else {console.error('msg not support')}} else {console.error('msg not support')}this.receiveMsgFromHtml = msg;// 3、将另一个消息端口(如端口0)发送到HTML侧,由HTML侧保存并使用。this.webViewController.postMessage('__init_port__', [this.ports[0]], "*");})} catch (err) {console.error('err: ' + JSON.stringify(err))}}build() {Column() {Button('加载html文本内容').onClick(event => {this.webViewController.loadData("<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>","text/html","UTF-8");})Button('调用html的js函数').onClick(event => {this.webViewController.runJavaScript('htmlTest()')})Button('web组件初始化完成后注入').onClick(event => {this.webViewController.registerJavaScriptProxy(this.testObj, "testObjName", ["test"]);})Text(this.receiveMsgFromHtml).fontSize(33)Button('给html端发消息').onClick(() => {try {if (this.ports && this.ports[1]) {//4.给html发消息this.ports[1].postMessageEvent(this.sendFromEts)} else {console.error('ports init fail')}} catch (err) {console.error('ports init fail ' + JSON.stringify(err))}})// Web({ src: this.indexUrl, controller: this.webViewController })//   .darkMode(WebDarkMode.On) //设置深色模式//   .forceDarkAccess(true) //强制生效// Web({ src: $rawfile('window.html'), controller: this.webViewController })//   .javaScriptAccess(true)//   .multiWindowAccess(true)//   .onWindowNew(event=>{//     if (this.dialog) {//       this.dialog.close()//     }////     let popController: webview.WebviewController = new webview.WebviewController();////     this.dialog = new CustomDialogController({//       builder: NewWebViewComp({webviewController1: popController})//     })//     this.dialog.open()//     //将新窗口对应WebviewController返回给Web内核。//     //如果不需要打开新窗口请调用event.handler.setWebController接口设置成null。//     //若不调用event.handler.setWebController接口,会造成render进程阻塞。//     event.handler.setWebController(popController)//   })Web({ src: $rawfile('postMsg.html'), controller: this.webViewController })// Web({ src: $rawfile('local.html'), controller: this.webViewController })//   .onShowFileSelector(event => {//     //设置要上传的文件路径//     let fileList: Array<string> = []//     if (event) {//       event.result.handleFileList(fileList)//     }//     return true;//   })//   .geolocationAccess(true)//   .javaScriptAccess(true)//   .javaScriptProxy({//将对角注入到web端//     object: this.testObj,//     name: 'testObjName',//     methodList: ['test'],//     controller: this.webViewController//   })//   .onGeolocationShow(event => {//     AlertDialog.show({//       title: '位置权限请求',//       message: '是否允许获取位置信息',//       primaryButton: {//         value: '同意',//         action: () => {//           event.geolocation.invoke(event.origin, true, false);//         }//       },//       secondaryButton: {//         value: '取消',//         action: () => {//           if (event) {//             event.geolocation.invoke(event.origin, false, false)//           }//         }//       },//       cancel: () => {//         if (event) {//           event.geolocation.invoke(event.origin, false, false)//         }//       }////     })//   })}.width('100%').height('100%')}
}

相关文章:

ArkTS开发系列之Web组件的学习(2.9)

上篇回顾&#xff1a;ArkTS开发系列之事件&#xff08;2.8.2手势事件&#xff09; 本篇内容&#xff1a; ArkTS开发系列之Web组件的学习&#xff08;2.9&#xff09; 一、知识储备 Web组件就是用来展示网页的一个组件。具有页面加载、页面交互以及页面调试功能 1. 加载网络…...

postman接口工具的详细使用教程

Postman 是一种功能强大的 API 测试工具&#xff0c;可以帮助开发人员和测试人员轻松地发送 HTTP 请求并分析响应。以下是对 Postman 接口测试工具的详细介绍&#xff1a; 安装与设置 安装步骤 访问 Postman 官网&#xff0c;点击右上角的“Download”按钮。 选择你的操作系统…...

C语言经典例题-17

1.最小公倍数 正整数A和正整数B的最小公倍数是指能被A和B整除的最小的正整数&#xff0c;设计一个算法&#xff0c;求输入A和B的最小公倍数。 输入描述&#xff1a;输入两个正整数A和B。 输出描述&#xff1a;输出A和B的最小公倍数。 输入&#xff1a;5 7 输出&#xff1a…...

鸿蒙学习(-)

.ets文件结构 //页面入口 Entry //组件 Component struct test{//页面结构build(){//容器 **一个页面只能有一个根容器&#xff0c;父容器要有大小设置**}1、Column 组件 沿垂直方向布局的组件&#xff0c;可以包含子组件 接口 Column({space}) space的参数为string | numbe…...

【TB作品】MSP430G2553,单片机,口袋板, 烘箱温度控制器

题3 烘箱温度控制器 设计一个基于MSP430的温度控制器&#xff0c;满足如下技术指标&#xff1a; &#xff08;1&#xff09;1KW 电炉加热&#xff0c;最度温度为110℃ &#xff08;2&#xff09;恒温箱温度可设定&#xff0c;温度控制误差≦2℃ &#xff08;3&#xff09;实时显…...

PCM、WAV,立体声,单声道,正弦波等音频素材

1&#xff09;PCM、WAV音频素材&#xff0c;分享给将要学习或者正在学习audio开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 常用的Audio PCM WAV不同采样率&#xff0c;不同采样深度&#…...

基于深度学习的图像去雾

基于深度学习的图像去雾 图像去雾是指从有雾的图像中恢复清晰图像的过程。传统的图像去雾方法&#xff08;如暗原色先验、图像分层法等&#xff09;在某些情况下表现良好&#xff0c;但在复杂场景下效果有限。深度学习方法利用大量的数据和强大的模型能力&#xff0c;在图像去…...

中国电子学会青少年编程等级考试真题下载

全国青少年软件编程等级考试真题下载&#xff0c;有答案解析 1. 图形化Scratch一级下载 链接&#xff1a;https://pan.baidu.com/s/1C9DR9-hT1RUY3417Yc8RZQ?pwdg8ac 提取码&#xff1a;g8ac 2.图形化Scratch二级下载 链接&#xff1a;https://pan.baidu.com/s/1HI7GaI4ii…...

PostMan动态设置全局变量

1. 前言 在开发过程中调试接口&#xff0c;一般都会使用PostMan。 其中有几个变量可能是好几个接口共用的&#xff0c;就会出现频繁手动复制(ctrlc)、粘贴(ctrlv)的情况。 这个过程得非常留意&#xff0c;生怕复制错了&#xff0c;或删减了某些东西&#xff0c;导致接口报错。…...

ACL 2023事件相关(事件抽取、事件关系抽取、事件预测等)论文汇总

ACL 2023事件抽取相关(事件抽取、事件关系抽取、事件预测等)论文汇总&#xff0c;后续会更新全部的论文讲解。 Event Extraction Code4Struct: Code Generation for Few-Shot Event Structure Prediction 数据集&#xff1a;ACE 2005 动机&#xff1a;与自然语言相比&#xf…...

力扣:59. 螺旋矩阵 II(Java,模拟)

目录 题目描述示例 1&#xff1a;代码实现 题目描述 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5…...

记录SpringBoot启动报错解决

记录SpringBoot启动报错解决 报错现场 Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class Action: Consider the following:If you want an embedde…...

微软代码页标识符 (Code Page Identifiers)

代码页标识符 (Code Page Identifiers) 双语对照 Identifiere标识符.NET Name.NET 名称Additional information其他信息037IBM037IBM EBCDIC US-CanadaIBM EBCDIC US-Canada437IBM437OEM United StatesOEM 美国500IBM500IBM EBCDIC InternationalIBM EBCDIC 国际字符集708ASMO…...

刷题——二叉树的后续遍历

方法一&#xff1a;双指针法 void postorder(TreeNode* root, vector<int>&res){if(root NULL) return;postorder(root->left,res);postorder(root->right,res);res.push_back(root->val);}vector<int> postorderTraversal(TreeNode* root) {// wri…...

用友U8 Cloud smartweb2.showRPCLoadingTip.d XXE漏洞复现

0x01 产品简介 用友U8 Cloud 提供企业级云ERP整体解决方案,全面支持多组织业务协同,实现企业互联网资源连接。 U8 Cloud 亦是亚太地区成长型企业最广泛采用的云解决方案。 0x02 漏洞概述 用友U8 Cloud smartweb2.showRPCLoadingTip.d 接口处存在XML实体,攻击者可通过该漏…...

React中的事件绑定的四种方式

1.在构造函数中绑定事件 constructor(props) {super(props);this.handleClick this.handleClick.bind(this);}2.在调用时显式绑定 <button onClick{this.handleClick.bind(this)}>Click me</button>3.使用箭头函数 handleClick () > {console.log(Button cli…...

小文件过多的解决方法(不同阶段下的治理手段,SQL端、存储端以及计算端)

上一篇介绍了小文件出现的原因以及为什么治理小文件问题迫在眉睫&#xff0c;本篇将为读者讲述在不同阶段下小文件治理的最佳手段以及如何针对性的解决小文件过多的问题。 小文件过多如何解决、治理方法 小文件是特别常见的现象&#xff0c;解决小文件问题迫在眉睫&#xff0…...

SGPT论文阅读笔记

这是篇想要用GPT来提取sentence embedding的工作&#xff0c;提出了两个框架&#xff0c;一个是SGPT-BE&#xff0c;一个是SGPT-CE&#xff0c;分别代表了Bi-Encoder setting和Cross-Encoder setting。CE的意思是在做阅读理解任务时&#xff0c;document和query是一起送进去&am…...

虚拟机与主机的网络桥接

虚拟机网路桥接是一种网络配置方式&#xff0c;它允许虚拟机与物理网络中的其他设备直接通信。在桥接模式下&#xff0c;虚拟机的网络接口通过主机的物理网卡连接到局域网中&#xff0c;就像主机本身一样&#xff0c;拥有自己的MAC地址和IP地址。这种方式使得虚拟机可以像独立的…...

urfread刷算法题day1|LeetCode2748.美丽下标的数目

题目 题目链接 LeetCode2748.美丽下标对的数目 题目描述 给你一个下标从 0 开始的整数数组 nums 。 如果下标对 i、j 满足 0 ≤ i < j < nums.length &#xff0c; 如果 nums[i] 的 第一个数字 和 nums[j] 的 最后一个数字 互质 &#xff0c; 则认为 nums[i] 和 nums…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...