位置、Cookie、缓存:华为鸿蒙 ArkWeb 数据管理全攻略 原创
本文旨在深入探讨华为鸿蒙HarmonyOS Next系统(截止目前API12)的技术细节,基于实际开发实践进行总结。
主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。
本文为原创内容,任何形式的转载必须注明出处及原作者。
引言
ArkWeb 是华为鸿蒙系统提供的一个强大的 Web 应用框架,允许开发者将 Web 页面嵌入到鸿蒙应用中,并与之进行交互。它可以极大地降低开发成本,提升开发效率,并实现跨平台的 Web 应用开发。ArkWeb 支持多种使用场景,例如:
- 应用集成 Web 页面: 应用可以在页面中使用 Web 组件,嵌入 Web 页面内容,以降低开发成本,提升开发、运营效率。
- 浏览器网页浏览场景: 浏览器类应用可以使用 Web 组件,打开三方网页,使用无痕模式浏览 Web 页面,设置广告拦截等。
- 小程序: 小程序类宿主应用可以使用 Web 组件,渲染小程序的页面。
Web 组件的生命周期
ArkWeb 的 Web 组件提供了丰富的生命周期回调接口,开发者可以通过这些接口感知 Web 组件的生命周期状态变化,并进行相关的业务处理。Web 组件的状态主要包括: - Controller 绑定到 Web 组件: 当 Controller 成功绑定到 Web 组件时触发该回调,推荐在此事件中注入 JS 对象、设置自定义用户代理等。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
Web({
// ...
.onControllerAttached(() => {
// 推荐在此 loadUrl、设置自定义用户代理、注入 JS 对象等
console.log('onControllerAttached execute');
})
// ...
})
}
}
}
- 网页加载开始: 网页开始加载时触发该回调,推荐在此回调中执行 JavaScript 脚本 loadUrl 等。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
Web({
// ...
.onPageBegin((event) => {
if (event) {
console.log('onPageBegin url:' + event.url);
}
})
// ...
})
}
}
}
- 网页加载进度: 告知开发者当前页面加载的进度。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
Web({
// ...
.onProgressChange((event) => {
if (event) {
console.log('newProgress:' + event.newProgress);
}
})
// ...
})
}
}
}
- 网页加载结束: 网页加载完成时触发该回调,推荐在此回调中执行 JavaScript 脚本。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
Web({
// ...
.onPageEnd((event) => {
if (event) {
console.log('onPageEnd url:' + event.url);
}
})
// ...
})
}
}
}
- 页面即将可见: 在创建自定义组件的新实例后,在执行其 build 函数前执行,建议在此设置 WebDebug 调试模式、设置 Web 内核自定义协议 URL 的跨域请求与 fetch 请求的权限、设置 Cookie 等。
@Entry
@Component
struct WebComponent {
// ...
aboutToAppear(): void {
try {
webview.WebviewController.setWebDebuggingAccess(true);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
}
build() {
Column() {
// ...
}
}
}
- 应用渲染进程异常退出: 应用渲染进程异常退出时触发该回调,可以在此回调中进行系统资源的释放、数据的保存等操作。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
// ...
.onRenderExited((event) => {
if (event) {
console.log('onRenderExited reason:' + event.renderExitReason);
}
})
// ...
}
}
}
- 组件卸载消失: 组件卸载消失时触发此回调。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
// ...
.onDisAppear(() => {
promptAction.showToast({
message: 'The web is hidden',
duration: 2000
});
})
// ...
}
}
}
Web 组件的性能指标
网页加载过程中需要关注一些重要的性能指标,例如 FCP(首次内容绘制)、FMP(首次有效绘制)、LCP(最大内容绘制)等。ArkWeb 提供了如下接口来通知开发者:
- onFirstContentfulPaint: 网页首次内容绘制的回调函数。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
// ...
.onFirstContentfulPaint(event => {
if (event) {
console.log("onFirstContentfulPaint:" + "[navigationStartTick]:" + event.navigationStartTick + ", [firstContentfulPaintMs]:" + event.firstContentfulPaintMs);
}
})
// ...
}
}
}
- onFirstMeaningfulPaint: 网页首次有效绘制的回调函数。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
// ...
.onFirstMeaningfulPaint(event => {
if (event) {
console.log("onFirstMeaningfulPaint:" + "[navigationStartTick]:" + event.navigationStartTick + ", [firstMeaningfulPaintMs]:" + event.firstMeaningfulPaintMs);
}
})
// ...
}
}
}
- onLargestContentfulPaint: 网页绘制页面最大内容的回调函数。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
// ...
.onLargestContentfulPaint(event => {
if (event) {
console.log("onLargestContentfulPaint:" + "[navigationStartTick]:" + event.navigationStartTick + ", [largestContentfulPaintMs]:" + event.largestContentfulPaintMs);
}
})
// ...
}
}
}
管理位置权限
ArkWeb 提供了位置权限管理能力。开发者可以通过 onGeolocationShow() 接口对某个网站进行位置权限管理。Web 组件根据接口响应结果,决定是否赋予前端页面权限。获取设备位置,需要开发者配置 ohos.permission.LOCATION、ohos.permission.APPROXIMATELY_LOCATION、ohos.permission.LOCATION_IN_BACKGROUND,并同时在设备上打开应用的位置权限和控制中心的位置信息。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
// ...
.onGeolocationShow((event) => { // 地理位置权限申请通知
AlertDialog.show({
title: '位置权限请求',
message: '是否允许获取位置信息',
primaryButton: {
value: 'cancel',
action: () => {
if (event) {
event.geolocation.invoke(event.origin, false, false); // 不允许此站点地理位置权限请求
}
},
},
secondaryButton: {
value: 'ok',
action: () => {
if (event) {
event.geolocation.invoke(event.origin, true, false); // 允许此站点地理位置权限请求
}
},
},
});
})
// ...
}
}
}
管理 Cookie 及数据存储
Cookie 是网络访问过程中,由服务端发送给客户端的一小段数据。客户端可持有该数据,并在后续访问该服务端时,方便服务端快速对客户端身份、状态等进行识别。当 Cookie SameSite 属性未指定时,默认值为 SameSite=Lax,只在用户导航到 cookie 的源站点时发送 cookie,不会在跨站请求中被发送。
@Entry
@Component
struct WebComponent {
// ...
build() {
Column() {
// ...
Button('configCookieSync')
.onClick(() => {
try {
webview.WebCookieManager.configCookieSync('https://www.example.com', 'value=test');
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
// ...
}
}
}
缓存与存储管理
在访问网站时,网络资源请求是相对比较耗时的。开发者可以通过 Cache、Dom Storage 等手段将资源保存到本地,以提升访问同一网站的速度