HarmonyNote.TOP鸿蒙开发笔记

Web组件加载沙箱HTML页面实践

鸿蒙提供了丰富的各种视图组件,同时还支持加载沙箱目录下的HTML页面并显示。我的需求是从一个网络资源地址下载一个zip压缩包到files沙箱目录下,然后解压缩到指定文件夹,最后在一个Entry页面里用Web组件加载解压出来的HTML页面并显示。需求不难,第一步下载zip压缩文件:

const downloadTask = await request.downloadFile(AppContextInstance.context, {
  url: downloadUrl,
  filePath: targetPath
})

在解开压缩文件之前,为了保险起见我写了一个方法检查目标解压目录是否存在,如果不存在则创建目录。示例代码如下:

// 确保目标目录存在,如果不存在则创建
public async ensureDirExists(dir: string): Promise<void> {
  try {
    fileIo.accessSync(dir);
  } catch (error) {
    try {
      fileIo.mkdirSync(dir, true);
    } catch (err2) {
      console.log(err2)
    }
  }
}

然后就是解开压缩文件了,这一步代码比较简单,示例如下:

zlib.decompressFile(zipFileAbsPath, unzipDirAbsPath)

解开压缩文件之后,就是通过router跳转到加载HTML的Entry Page,示例代码如下:

router.pushUrl({
  url: 'web_view/WebPage',
  params: {
    'openUrl': 'file://' + this.absPath(fileName, fileRelativePath)
  }
})

为了可以灵活加载不同的HTML文件,我通过传递params的方式将目标沙箱HTML文件的路径以openUrl的参数名传递过去,Entry Page页面示例代码如下:

import { webview } from '@kit.ArkWeb'
import { router } from '@kit.ArkUI'

@Entry
@Component
struct WebPage {
  openUrl: string = ''
  webCtl: webview.WebviewController = new webview.WebviewController()

  aboutToAppear(): void {
    const paramsObj = router.getParams() as Record<string, boolean | number | string>
    if (paramsObj) {
      this.openUrl = paramsObj['openUrl'] as string
    }
  }

  build() {
    Column() {
      Text(this.openUrl)
      Web({
        src: this.openUrl,
        controller: this.webCtl
      })
        .domStorageAccess(true)
        .width('100%')
        .height('80%')
        .showBorderEdge()
    }.width('100%')
    .height('100%')
  }
}

然而当一切准备就绪,在真机上测试的时候却发现HTML页面始终没有加载出来,进入沙箱目录检查发现是创建解压文件夹那一步出错了,虽然文件夹还没有创建,但是fileIo.accessSync(dir)这行代码并没有抛出异常,也就导致fileIo.mkdirSync(dir, true)这行代码没有执行,进而解压文件也没有放入指定目录,自然Web组件就无法加载一个不存在的路径的HTML页面了。于是就粗暴地将第二步改为直接创建文件夹了,示例代码如下:

// 确保目标目录存在,如果不存在则创建
public async createDir(dir: string): Promise<void> {
  try {
    fileIo.mkdirSync(dir, true);
  } catch (err2) {
    console.log(err2)
  }
}

改了之后,就顺利地完成了下载zip压缩文件,然后解压到指定文件夹,最后跳转到Entry Page成功地加载并显示出了本地沙箱HTML页面。略有遗憾的是下载zip压缩文件里的图片资源含有中文命名,zlib解压中文文件名出来是乱码,导致Web加载HTML页面也无法正常显示部分图片。