鸿蒙Next开发日记 Day13 - Web组件的使用与避坑

程序中经常会用到使用H5展示内容的情况,更何况Hybrid的情况。
鸿蒙NEXT也提供了方便的网页展示容器--Web组件,是Web,不是WebView,鸿蒙没有WebView。
下面是一个示例代码
import { webview } from '@kit.ArkWeb';
import StringUtil from '../../utils/StringUtil';
import LoadingDialogView from '../../view/Dialog/LoadingDialogView'
@Builder
export function WebViewPageBuilder(name: string, param: Object) {
WebViewPage({ param: param as Record<string, Object> })
}
@Component
struct WebViewPage {
@Builder
WebView() {
Web({ src: this.url, controller: this.controller })
.javaScriptAccess(true)
.geolocationAccess(true)
.imageAccess(true)
.onlineImageAccess(true)
.domStorageAccess(true)
.fileAccess(true)
.mediaPlayGestureAccess(true)
.mixedMode(MixedMode.Compatible)
.onTitleReceive((event) => {
if (event) {
this.title = event.title
}
})
.onProgressChange((event) => {
if (event) {
this.progressPercentage = event.newProgress
}
})
.onHttpErrorReceive((event) => {
if (event) {
console.log('url:' + event.request.getRequestUrl());
console.log('isMainFrame:' + event.request.isMainFrame());
console.log('isRedirect:' + event.request.isRedirect());
console.log('isRequestGesture:' + event.request.isRequestGesture());
console.log('getResponseData:' + event.response.getResponseData());
console.log('getResponseEncoding:' + event.response.getResponseEncoding());
console.log('getResponseMimeType:' + event.response.getResponseMimeType());
console.log('getResponseCode:' + event.response.getResponseCode());
console.log('getReasonMessage:' + event.response.getReasonMessage());
let result = event.request.getRequestHeader();
console.log('The request header result size is ' + result.length);
for (let i of result) {
console.log('The request header key is : ' + i.headerKey + ' , value is : ' + i.headerValue);
}
let resph = event.response.getResponseHeader();
console.log('The response header result size is ' + resph.length);
for (let i of resph) {
console.log('The response header key is : ' + i.headerKey + ' , value is : ' + i.headerValue);
}
}
})
// .onControllerAttached(() => {
// this.controller.loadUrl(this.url)
// })
.width("100%")
.flexGrow(1)
.layoutWeight(1)
}
build() {
NavDestination() {
Column() {
if (!StringUtil.isNullStr(this.url)) {
if (this.progressPercentage > 0 && this.progressPercentage < 100) {
Progress({ value: this.progressPercentage, total: 100, type: ProgressType.Linear })
.width("100%").height(2).backgroundColor($r('app.color.background_main'))
.style({ strokeWidth: 2 })
}
this.WebView()
}
}
.backgroundColor("#FFAAFF")
.width("100%").height("100%")
}.title(this.title)
.onWillAppear(() => {
this.url = this.param.url as string
})
.onAppear(() => {
})
.onShown(() => {
})
}
param: Record<string, Object> = {}
@State url: string = ""
@State title: string = ""
controller: webview.WebviewController = new webview.WebviewController()
@State avoidMode: WebKeyboardAvoidMode = WebKeyboardAvoidMode.RESIZE_VISUAL;
@Consume('navPathStack') navPathStack: NavPathStack;
@State progressPercentage: number = 0
loadingController: CustomDialogController = new CustomDialogController({
builder: LoadingDialogView(),
autoCancel: true,
customStyle: true,
})
}通过以上代码就可以实现一个带进度条的简易浏览器。

这里有几个坑需要注意一下。
1. 多给Web组件添加一些权限,有些网页使用了本地存储等技术,权限未开的情况下会出现加载不出内容的情况,然后还定位不出原因。具体权限添加如下:
.javaScriptAccess(true).geolocationAccess(true)
.imageAccess(true)
.onlineImageAccess(true)
.domStorageAccess(true)
.fileAccess(true)
.mediaPlayGestureAccess(true)
.mixedMode(MixedMode.Compatible)
2. 是我在使用模拟器调试Web组件时出现的问题,模拟器是可以设置http代理的,当你开启模拟器代理时,会出现Web组件在加载域名地址失败情况,DNS解析失败了。现象就是内容是空白。

为了避免不必要的麻烦,调试Web组件时,就把代理关了吧。
网友留言(0 条)