鸿蒙OS开发实例:【Web网页】

 背景

HarmonyOS平台通过Web控件可支持网页加载展示,Web在中是作为专项参考的。

本篇文章将从Android和iOS平台研发角度出发来实践学习API功能

说明

  1. 整个示例是以HarmonyOS开发文档网址作为加载目标
  2. 页面布局增加了三个按钮“后退”,“前进”, “刷新”

效果

Screenshot_20231130120249783.png

准备

  1. 请参照
鸿蒙OS开发更多内容↓点击HarmonyOS与OpenHarmony技术
鸿蒙技术文档开发知识更新库gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md在这。或+mau123789学习,是v喔

熟读HarmonyOS Web组件指导

搜狗高速浏览器截图20240326151547.png

2.创建一个Demo工程,选择Stage模型。

实践总结

  1. UA可以设置,但无法通过API拿到自己设置的UA值
  2. 文件可以下载,但用户没有控制权
  3. 用户无法控制定位权限申请
  4. Web控件当前需要将UA设置为Android或者iOS特征的UA,大部分主流网站没有适配鸿蒙Web
  5. 鸿蒙UA特征不明显 Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36

开始

页面容器设置为沉浸式

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';export default class EntryAbility extends UIAbility {onWindowStageCreate(windowStage: window.WindowStage) {// 1.获取应用主窗口。let windowClass: window.Window = null;windowStage.getMainWindow((err, data) => {if (err.code) {console.error('Failed to obtain the main window. Cause: ' + JSON.stringify(err));return;}windowClass = data;console.info('Succeeded in obtaining the main window. Data: ' + JSON.stringify(data));// 2.实现沉浸式效果:设置导航栏、状态栏显示。windowClass.setWindowSystemBarEnable(['status','navigation'], (err) => {if (err.code) {console.error('Failed to set the system bar to be visible. Cause:' + JSON.stringify(err));return;}console.info('Succeeded in setting the system bar to be visible.');});})//获取当前应用内最后显示的窗口,使用callback异步回调window.getLastWindow(this.context).then((result: window.Window) => {result.setWindowSystemBarEnable(['status', 'navigation'])result.setWindowLayoutFullScreen(true);})windowStage.loadContent('pages/Index', (err, data) => {if (err.code) {hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');return;}hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');});}}

创建WebView组件

文件路径

根目录/ets/entry/src/main/pages/WebView.ts

注册页面 main_pages.json

{"src": ["pages/Index","pages/WebView"]
}

功能实现

Cookie管理指导

网页调试

功能介绍
  1. 支持多窗口
  2. 多窗口返回关闭
  3. 加载进度提示
  4. 警告框,确认框,提示框
  5. 权限申请
  6. 输出调试日志
  7. 非http或https协议拦截
import web_webview from '@ohos.web.webview';
import router from '@ohos.router';
import common from '@ohos.app.ability.common';
import Url from '@ohos.url'web_webview.once("webInited", () => {console.log("setCookie")web_webview.WebCookieManager.setCookie("https://developer.harmonyos.com/", "author=harvey")
})//在同一page页有两个web组件。在WebComponent新开窗口时,会跳转到NewWebViewComp。
@CustomDialog
struct NewWebViewComp {private controller?: CustomDialogControllerprivate webviewController: web_webview.WebviewController = new web_webview.WebviewController()build() {Column() {Web({ src: "", controller: this.webviewController }).javaScriptAccess(true).multiWindowAccess(false).domStorageAccess(true).onWindowExit(() => {console.info("NewWebViewComp onWindowExit")if (this.controller) {this.controller.close()}})}}
}@Entry
@Component
struct Index {//www.useragentinfo.com// @State webURL: string = 'https://m.bilibili.com/'    //'https://developer.harmonyos.com/'// @State webURL: string = 'https://www.baidu.com'@State webURL: string = 'https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/start-overview-0000001478061421-V3?catalogVersion=V3'@State back: boolean = true@State forward: boolean = false@State showProgress: boolean = false@State currentProgress: number = 0@State buttonColorFocusColor: number = Color.Black@State buttonColorDisableColor: number = Color.Gray@State currentButtonColor: number = this.buttonColorFocusColorprivate webviewController: web_webview.WebviewController = new web_webview.WebviewController();private context = getContext(this) as common.UIAbilityContext;dialogController: CustomDialogController | null = nullaboutToAppear() {web_webview.WebviewController.setWebDebuggingAccess(true)let params = router.getParams()if (params) {this.webURL = params['targetUrl'];}}build() {Column() {Stack() {Web({ src: this.webURL, controller: this.webviewController }).width('100%').height('100%').userAgent('Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36 HarveyHarmonyOS/1.0.0').multiWindowAccess(true).javaScriptAccess(true).geolocationAccess(true).imageAccess(true).onlineImageAccess(true).domStorageAccess(true).fileAccess(true).mediaPlayGestureAccess(true).mixedMode(MixedMode.Compatible).onTitleReceive((info) => {console.log('标题栏: ' + info.title)}).onProgressChange((progress) => {console.log('当前加载进度 ' + progress.newProgress)this.currentProgress = progress.newProgressif (progress.newProgress >= 0 && progress.newProgress < 100) {this.showProgress = true} else if (progress.newProgress == 100) {this.showProgress = false}if (this.webviewController.accessForward()) {this.forward = truethis.currentButtonColor = this.buttonColorFocusColor} else {this.forward = falsethis.currentButtonColor = this.buttonColorDisableColor}console.log('userAgent: ' + this.webviewController.getUserAgent())}).onErrorReceive((error) => {console.log(error.request.getRequestUrl())console.log(JSON.stringify(error.error))}).onHttpErrorReceive((error) => {console.log(JSON.stringify(error.response))}).onSslErrorEventReceive((info) => {}).onRenderExited(() => {console.log('onRenderExited')}).onUrlLoadIntercept((info) => {if(!info.data.toString().toLowerCase().startsWith("https://") || !info.data.toString().toLowerCase().startsWith("https://")){console.log('拦截信息: ' + JSON.stringify(info))return true;}console.log('信息: ' + JSON.stringify(info))//false : 不拦截   true: 拦截return false}).onDownloadStart( (event) => {AlertDialog.show({title: event.url,message: event.url,primaryButton: {value: 'cancel',action: () => {}}})}).onAlert((event) => {AlertDialog.show({title: event.url,message: event.message,confirm: {value: 'onAlert',action: () => {event.result.handleConfirm()}},cancel: () => {event.result.handleCancel()}})return true}).onConfirm((event) => {AlertDialog.show({title: event.url,message: event.message,confirm: {value: 'onConfirm',action: () => {event.result.handleConfirm()}},cancel: () => {event.result.handleCancel()}})return true;}).onPrompt((event) => {AlertDialog.show({title: event.url,message: event.message,primaryButton: {value: 'cancel',action: () => {event.result.handleCancel()}},secondaryButton: {value: 'ok',action: () => {event.result.handleConfirm()}},cancel: () => {event.result.handleCancel()}})return true;}).onConsole((msg) => {console.error('网页日志:' + JSON.stringify(msg.message.getMessage()))return true}).onWindowNew((event) => {console.log('新开window')if (!event.isAlert) {router.pushUrl({ url: 'custompages/WebView', params: {"targetUrl": event.targetUrl} }).then(() => {console.info('Succeeded in jumping to the second page.')}).catch((error) => {console.log(error)})} else {if (this.dialogController) {this.dialogController.close()}let popController: web_webview.WebviewController = new web_webview.WebviewController()this.dialogController = new CustomDialogController({builder: NewWebViewComp({ webviewController: popController })})this.dialogController.open()//将新窗口对应WebviewController返回给Web内核。//如果不需要打开新窗口请调用event.handler.setWebController接口设置成null。//若不调用event.handler.setWebController接口,会造成render进程阻塞。event.handler.setWebController(popController)}}).onWindowExit(() => {console.log('已推出window')}).onGeolocationHide(() => {console.log('geo隐藏')}).onGeolocationShow((info) => {info.geolocation.invoke(info.origin, false, false)console.log(info.origin + ' 有定位需求')}).onPageBegin((info) => {console.error(info.url)let host = Url.URL.parseURL(info.url).hosttry {let cookie = web_webview.WebCookieManager.getCookie(host)console.log('Bcookie: ' + cookie)} catch (e) {console.error(e)}}).onPageEnd((info) => {let host = Url.URL.parseURL(info.url).hosttry {let cookie = web_webview.WebCookieManager.getCookie(host)console.log('Bcookie: ' + cookie)} catch (e) {console.error(e + ' ' + info.url)}}).onBeforeUnload((info) => {return false}).onRefreshAccessedHistory((info) => {}).onResourceLoad(() => {}).onFullScreenEnter((info) => {}).onFullScreenExit(() => {}).onPermissionRequest((event) => {AlertDialog.show({title: 'title',message: event.request.getAccessibleResource()[0],primaryButton: {value: 'deny',action: () => {event.request.deny()}},secondaryButton: {value: 'onConfirm',action: () => {event.request.grant(event.request.getAccessibleResource())}},cancel: () => {event.request.deny()}})}).onInterceptKeyEvent((info) => {console.log(info.keyCode + ' ' + info.keyText)return false}).onPageVisible((info) => {console.log(info.url)})if (this.showProgress) {Progress({ value: this.currentProgress, total: 100, type: ProgressType.Linear }).width('100%').height(45)}}.height('93%').alignContent(Alignment.TopStart)Row() {Text('后退').fontSize(18).enabled(this.back).onClick(() => {if (this.webviewController.accessBackward()) {this.webviewController.backward()} else {if ("1" === router.getLength()) {this.context.terminateSelf()} else {router.back()}}}).width('30%').height('100%').textAlign(TextAlign.Center)Text('前进').fontSize(18).fontColor(this.currentButtonColor).onClick(() => {if (this.webviewController.accessForward()) {this.webviewController.forward()}}).width('30%').height('100%').textAlign(TextAlign.Center)Text('刷新').fontSize(18).fontColor(Color.Black).onClick(() => {this.webviewController.refresh()}).width('30%').height('100%').textAlign(TextAlign.Center)}.width('100%').height('5%').backgroundColor(Color.White).justifyContent(FlexAlign.SpaceBetween)}.width('100%').height('100%').padding({ top: px2vp(111) })}
}

鸿蒙知识持续更新中,关注我点赞不迷路喔!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/785292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TransmittableThreadLocal 问题杂记

0、前言 TransmittableThreadLocal&#xff0c;简称 TTL&#xff0c;是阿里巴巴开源的一个Java库&#xff0c;它能够实现ThreadLocal在多线程间的值传递&#xff0c;适用于使用线程池、异步调用等需要线程切换的场景&#xff0c;解决了ThreadLocal在使用父子线程、线程池时不能…

2022 Tesla AI Day -特斯拉自动驾驶FSD的进展和算法软件技术之数据以及虚拟

2022 Tesla AI Day -特斯拉自动驾驶FSD的进展和算法软件技术之数据以及虚拟 附赠自动驾驶学习资料和量产经验&#xff1a;链接 人工智能算法犹如电影的主演&#xff0c;我们很多时候看电影只看到主演们的精彩&#xff0c;但其实电影的创意和呈现都来自于背后的导演和制片等团队…

数论与线性代数——整除分块【数论分块】的【运用】【思考】【讲解】【证明(作者自己证的QWQ)】

文章目录 整除分块的思考与运用整除分块的时间复杂度证明 & 分块数量整除分块的公式 & 公式证明公式证明 代码code↓ 整除分块的思考与运用 整除分块是为了解决一个整数求和问题 题目的问题为&#xff1a; ∑ i 1 n ⌊ n i ⌋ \sum_{i1}^{n} \left \lfloor \frac{n}{…

让工作自动化起来!无所不能的Python

让工作自动化起来&#xff01;无所不能的Python 一、Python是办公自动化的重要工具二、Python是提升职场竞争力的利器三、Python是企业数字化的重要平台四、Python是AI发展的重要通道之一内容简介作者简介前言读者对象如何阅读本书购买链接参与方式 随着我国企业数字化和信息化…

metasploit使用及内网笔记

1 基本操作 Metasploit就是一个漏洞框架。它的全称叫做The Metasploit Framework&#xff0c;简称叫做MSF。Metasploit作为全球最受欢迎的工具&#xff0c;不仅仅是因为它的方便性和强大性&#xff0c;更重要的是它的框架。它允许使用者开发自己的漏洞脚本&#xff0c;从而进行…

Unix 网络编程, Socket 以及bind(), listen(), accept(), connect(), read()write()五大函数简介

Unix网络编程是针对类Unix操作系统&#xff08;包括Linux、BSD以及其他遵循POSIX标准的操作系统&#xff09;进行网络通信开发的技术领域。网络编程涉及创建和管理网络连接、交换数据以及处理不同层次网络协议栈上的各种网络事件。在Unix环境中&#xff0c;网络编程通常涉及到以…

前后端数据交互

前后端数据交互 网页上所有的数据都是来源于后端&#xff0c;比如淘宝或者京东的秒杀&#xff0c;用户的登陆或者注册&#xff0c;这些都需要借助于后端来存储数据。我们前端需要做的就是把数据发送给后端&#xff0c;后端发送给我们的数据我们要拿到把它显示到页面上&#xff…

leetcode131分割回文串

递归树 下面这个代码是遍历处所有的子串 #include <bits/stdc.h> using namespace std; class Solution { public:vector<vector<string>> vvs;vector<string> vs;vector<vector<string>> partition(string s) {dfs(0,s);return vvs;}vo…

【Linux】进程 基础概念

目录 1.进程的基本概念 1.1基本概念 1.11进程与程序的区别: 1.12并发与并行的区别 1.2进程的状态及转换 1.3描述进程—–PCB task_struct -- PCB的一种 1.4查看进程 ps 命令 top 命令 2.进程创建 3.进程状态 ps aux / ps axj 命令 进程状体具体讲解 R运行状态 S…

【Pt】马灯贴图绘制过程 01-制作基础色

目录 一、导入模型并烘焙 二、制作基础底漆 &#xff08;1&#xff09;底漆层 &#xff08;2&#xff09;水痕层 &#xff08;3&#xff09;指纹层 一、导入模型并烘焙 1. 导入模型&#xff0c;马灯模型如下所示 2. 在纹理集设置中点击“烘焙模型贴图” 设置输出大小为…

Linux基本指令篇

在前边&#xff0c;我们已经了解过了Linux操作系统的发展和应用&#xff0c;从该篇起&#xff0c;就正式进入对Linux的学习。 今天我们就来在Xshell上远程登录我们的云服务器。首先我们要知道自己云服务器的公网ip&#xff0c;然后修改一下密码。 点击跳转 修改完密码之后我们…

idea中 错误:找不到或无法加载主类

很神奇的就是maven打包是正常的&#xff0c;本来也是好好的&#xff0c;突然启动就报错了&#xff0c;我百度了很急&#xff0c;没什么结果&#xff0c;找了公司6年工作经验的老员工&#xff0c;还是搞了好久&#xff0c;我站了好久也是没解决。后来我也是在想maven的jar包都能…

JAVA学习笔记21

1.IDEA的使用 1.ctrl B 快速定位到方法 2.ctrl Y 快速删除行 3.ctrl D 快速复制行 4.ctrl H 查看继承的层级关系 5.快速格式化代码 ctrl shift L 6.alt R 快速允许程序 7.ctrl / 快速添加注释 1.包(软件包) 1.1包的三大作用 1.区分相同名字的类 2.当类很多的…

kubernetes用户权限管理详解——普通用户[kubeconfig]

原文&#xff1a; 学一下https://suxueit.com/article_detail/tdVymI4BWZdDRfKqnv1y K8s 的用户分为两类 普通用户&#xff1a;普通用户是指集群外部的人或系统管理&#xff0c;它们不由 Kubernetes 直接管理。普通用户的证书、密钥和权限管理通常由外部系统&#xff08;如企业…

【绘图案例-图形上下文栈 Objective-C语言】

一、接下来,我们来说这个“图形上下文栈” 1.我们还是把之前的copy这份儿代码复制一下,改个名字,叫做“02-图形上下文栈”, 好,我们把刚才那个圆形拿过来,那条线也拿过来,用CGContextAdd:这种方式, 把第一步,获取当前上下文,也拿过来,第三步,渲染,也拿过来, 打开…

买婴儿洗衣机怎么选择?四款优良婴儿洗衣机极力推荐

由于刚出生没多久的宝宝的肌肤相对来说会比较娇嫩&#xff0c;因此普遍的宝宝衣物都是采用纯棉材质&#xff0c;所以对于宝宝的衣服要特殊呵护&#xff0c;要求有无菌、无刺激的清洗环境。然而婴儿专用的洗衣机就应运而生&#xff01;婴儿洗衣机的优点很多&#xff0c;一是省时…

从 Azure 部署生成本地 .NET 密钥

作者&#xff1a;Frank Boucher 排版&#xff1a;Alan Wang 通常&#xff0c;示例项目以一些“魔术字符串”开始&#xff0c;这些变量包含与部署或外部资源相关的 URL 和关键信息&#xff0c;我们必须更改这些信息才能使用示例。例如在 .NET 中&#xff0c;它可能如下所示&…

Android 开发投屏软件

一、背景 作为Android开发总会有给他人share自己APP情况&#xff0c;一般在线会议投屏&#xff0c;总是需要在手机上安装对应会议软件特别麻烦~ 二、投屏 Android Studio已经自带了投屏能力&#xff0c;可以在电脑端直接控制手机&#xff0c;同步起来非常方便简单 打开步骤 …

linux ubuntu 在保存文件不被允许,但是root权限

现象&#xff1a;MobaXterm_Personal_2登录到服务器&#xff0c;切换到root用户&#xff0c;然后使用MobaXterm_Personal_2自带的编辑器&#xff0c;编写文件&#xff0c;进行保存不被允许&#xff1b;查看目录root是有权限进行修改文件的&#xff0c;然后使用vim进行修改保存&…

阿里云OSS, 跨域请求, No ‘Access-Control-Allow-Origin‘

问题 阿里云OSS, 跨域请求, No ‘Access-Control-Allow-Origin’ 错误标签&#xff1a;阿里云OSS, 跨域请求, No ‘Access-Control-Allow-Origin’ 浏览器具体报错内容&#xff1a; Access to XMLHttpRequest at ‘https://xxx.oss-cn-guangzhou.aliyuncs.com/xxx.jpg’ from …