HarmonyOS鸿蒙Next Web网页
背景
HarmonyOS Next平台通过Web控件可支持网页加载展示,Web在HarmonyOS官方指导中是作为专项介绍的。
本篇文章将从Android和iOS平台研发角度出发来实践学习API功能
说明
- 整个示例是以HarmonyOS Next开发文档网址作为加载目标
- 页面布局增加了三个按钮“后退”,“前进”, “刷新”
效果
准备
- 请参照官方指导,创建一个Demo工程,选择Stage模型
- 熟读HarmonyOS Web组件指导 developer.harmonyos.com/cn/docs/doc…
实践总结
- UA可以设置,但无法通过API拿到自己设置的UA值
- 文件可以下载,但用户没有控制权
- 用户无法控制定位权限申请
- Web控件当前需要将UA设置为Android或者iOS特征的UA,大部分主流网站没有适配鸿蒙Web
- 鸿蒙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) {
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));
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.');
});
})
window.getLastWindow(this.context).then(result => {
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"
]
}
功能实现
网页调试 推荐优先看
功能介绍
- 支持多窗口
- 多窗口返回关闭
- 加载进度提示
- 警告框,确认框,提示框
- 权限申请
- 输出调试日志
- 非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")
})
@Web
struct NewWebViewComp {
private controller?: CustomDialogController
private 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 {
@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.buttonColorFocusColor
private webviewController: web_webview.WebviewController = new web_webview.WebviewController();
private context = getContext(this) as common.UIAbilityContext;
dialogController: CustomDialogController | null = null
aboutToAppear() {
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.newProgress
if (progress.newProgress >= 0 && progress.newProgress < 100) {
this.showProgress = true
} else if (progress.newProgress == 100) {
this.showProgress = false
}
if (this.webviewController.accessForward()) {
this.forward = true
this.currentButtonColor = this.buttonColorFocusColor
} else {
this.forward = false
this.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()
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).host
try {
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).host
try {
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) })
}
}
更多关于HarmonyOS鸿蒙Next Web网页的实战教程也可以访问 https://www.itying.com/category-93-b0.html
博主您好,请教下如何给网页添加自定义的httpHeader
更多关于HarmonyOS鸿蒙Next Web网页的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
博主您好,请教一下,“UA可以设置,但无法通过API拿到自己设置的UA值”意思是通过.userAgent设置成功了,但是通过webviewcontroller.getuseragent拿到的仍然是原来的值吗?
项目名称
- 状态:进行中
- 创建者:张三
- 创建日期:2023-01-01
- 最后更新:2023-03-01
描述
这是一个示例项目,用于演示如何将HTML内容转换为Markdown。
成员
- 张三
- 李四
- 王五
目标
- 目标一
- 目标二
- 目标三
原来如此,被这个困扰了好久哈哈哈,谢谢博主,
HarmonyOS(鸿蒙操作系统)是华为开发的分布式操作系统,旨在为多种设备提供统一的用户体验。鸿蒙Next Web网页可能涉及鸿蒙系统在Web开发中的应用,如通过Web技术实现跨平台应用开发。开发者可以利用鸿蒙的分布式能力,结合Web技术,构建高效、灵活的应用。具体实现可能包括使用鸿蒙的JS框架、API接口等,确保应用在鸿蒙设备上的兼容性和性能优化。