HarmonyOS + Cordova:在线资源加载与拦截缓存问题排查


适用场景:

  • 页面部分资源来自线上(CDN / API / 在线 JS),在设备上加载异常。
  • 希望利用 Cordova 提供的拦截与缓存能力(Code Cache),但效果不稳定。
  • 想搞清楚 onInterceptWebRequestSetResourceReplace 等能力的正确用法与排错方式。

本文基于本仓库中 cordova/README.md 的高级用法示例,整理一套 在线资源 + 拦截缓存 的排查与实践指南。


1. 在线资源加载的基本路径

对于在线 JS/CSS/图片等资源,加载路径大致如下:
Web(index.html) ArkWeb WebView MainPage Cordova 拦截层 远端服务器 <script src="https://example.com/app.js"> 触发 onInterceptRequest/onInterceptWebRequest 可选: SetResourceReplace/拦截处理 发起真实网络请求 返回资源/错误 响应内容 执行 JS Web(index.html) ArkWeb WebView MainPage Cordova 拦截层 远端服务器

在 Cordova 提供的高级能力中,我们可以:

  • 对特定 URL 进行拦截替换:
    • 将线上资源替换为沙箱本地文件或 rawfile 中的资源。
  • 对 JS 做预编译(Code Cache),提升多次打开的加载速度。

2. 预编译与资源替换的示例结构

cordova/README.md 中给出了一个较完整的示例,这里抽取核心结构辅助理解:

2.1 配置结构(简化示意)

ts 复制代码
configs: Array<Config> = [
  {
    url: 'https://www.tongecn.com/example.js',
    localPath: 'example.js', // 文件在 rawfile 目录下
    options: {
      responseHeaders: [
        { headerKey: 'E-Tag', headerValue: 'xxx' },
        { headerKey: 'Last-Modified', headerValue: 'Wed, 21 Mar 2024 10:38:41 GMT' }
      ]
    }
  }
];

2.2 预编译逻辑(onControllerAttached 中)

ts 复制代码
mainPageCycle = new MainPageCycle().setOnControllerAttached((webviewController: webview.WebviewController, parentPage?: object) => {
  console.log('exec onControllerAttached');
  for (const config of this.configs) {
    let content = this.getUIContext().getHostContext()?.resourceManager.getRawFileContentSync(config.localPath);
    try {
      this.controller.precompileJavaScript(config.url, content, config.options)
        .then((errCode: number) => {
          console.log('precompile successfully!');
        }).catch((errCode: number) => {
          console.error('precompile failed.' + errCode);
        });
    } catch (err) {
      console.error('precompile failed!.' + err.code + err.message);
    }
  }
});

2.3 拦截替换逻辑(onInterceptWebRequest 中)

ts 复制代码
onInterceptWebRequest(request: WebResourceRequest, webTag: string): ESObject {
  let url = request.requestUrl;
  if (url === 'https://www.tongecn.com/v1.1.1/temp/test3.js') {
    // 替换到本地沙箱路径
    SetResourceReplace(webTag, url, 'https://localhost/data/storage/el2/base/files/test.js');
    // 或替换到 rawfile 文件
    // SetResourceReplace(webTag, url, 'https://www.example.com/test.js');
  }
  return null; // 交给默认流程继续
}

3. 常见问题一:预编译不生效 / 仍然每次都重新下载

3.1 排查要点

  1. precompileJavaScript 的 URL 必须与真实请求 URL 完全一致
    • 大小写、路径、查询参数都要一样。
  2. content 是否正确读取
    • getRawFileContentSync(localPath) 是否能读到非空字节;
    • localPath 是否位于正确的 rawfile 目录。
  3. 错误码与日志
    • precompile failed. 日志中的错误码能给出失败原因。

3.2 建议的日志与校验

在预编译前后加入详细日志:

ts 复制代码
console.log('[Precompile] url=', config.url, ' localPath=', config.localPath, ' size=', content?.length);
  • size 为 0 或 undefined,说明本地文件路径有问题。
  • url 与实际页面请求的 JS 地址不一致,预编译也不会命中。

4. 常见问题二:拦截替换后资源仍然请求线上地址

4.1 判断是否命中 onInterceptWebRequest

在回调的开头打印请求 URL:

ts 复制代码
onInterceptWebRequest(request: WebResourceRequest, webTag: string): ESObject {
  console.log('[Intercept] url=', request.requestUrl);
  // ... 其余逻辑
}
  • 若日志中完全看不到目标 URL:
    • 说明该请求可能是通过其它机制发起(如 XHR/fetch),需要结合具体内核文档确认拦截范围。
  • 若能看到 URL,但 SetResourceReplace 后仍请求线上:
    • 重点检查替换后的目标 URL 是否可访问、是否符合 Cordova 的内部协议约定。

4.2 资源替换关系图

SetResourceReplace 原始 URL
https://www.tongecn.com/v1.1.1/temp/test3.js 替换 URL
https://localhost/data/storage/el2/base/files/test.js 本地文件内容

提示:

  • 对于 https://localhost/... 这样的本地沙箱路径,要确保对应文件真实存在且可读。
  • 在调试时可以先把替换目标设为另一个可访问的线上地址,以验证 SetResourceReplace 是否生效。

5. 常见问题三:线上 JS 调试困难,不知道加载的是哪一个版本

当你对线上 JS 频繁迭代时,很容易出现"设备上到底加载了哪个版本"的困惑,尤其结合缓存/预编译后。

5.1 简单版本标识方案

在 JS 文件中加入版本号 LOG:

js 复制代码
console.log('[App] online script version = 2024-03-21-01');
  • 每次发布新版本,更新版本号;
  • 在设备上通过 Web console 或自建日志面板查看当前版本号。

5.2 与预编译配置联动

  • 将预编译配置的 options.responseHeadersE-Tag/Last-Modified 与版本号/构建时间关联。
  • 需要时可手动调整这些标记以控制缓存策略。

6. 端到端排查流程示例

假设你遇到如下问题:

  • 为某个在线 JS 做了预编译和资源替换;
  • 但设备上仍频繁访问线上地址,且性能没明显提升。

6.1 排查路线

否 是 否 是 否 是 否 是 预编译+替换不生效 Intercept 日志中有目标 URL 吗? 检查 onInterceptWebRequest 是否正确绑定/路径是否匹配 precompile 时使用的 URL 是否完全一致? 修改 precompile 配置与实际请求统一 替换目标 URL 是否可访问? 检查本地文件存在性/沙箱路径 Web console 中版本号/日志是否符合预期? 检查缓存/E-Tag/Last-Modified 配置 评估是否达到预期性能/流量目标


7. 将在线资源问题纳入整体调试体系

结合前几篇文章(工程结构、Web 调试、白屏排查等),你可以把"在线资源 + 拦截缓存"的问题纳入统一的调试体系:
页面异常/白屏 先确认 index.html/css/js 是否 200 无在线资源时是否正常 引入在线资源后开始异常 检查 onInterceptWebRequest/预编译配置 使用版本号与日志验证实际加载脚本

通过这套方法,你可以在 HarmonyOS + Cordova 混合项目中更从容地使用在线资源,同时利用 Cordova 的拦截与缓存特性实现性能优化,而不会被各种"线上/本地版本错乱"问题搞晕。

相关推荐
7***37452 小时前
HarmonyOS分布式能力的核心技术
分布式·华为·harmonyos
不爱吃糖的程序媛2 小时前
Cordova 定位功能在鸿蒙上的实现技术博客
华为·harmonyos
t***L2662 小时前
HarmonyOS国际化
华为·harmonyos
国霄3 小时前
(6)Kotlin/Js For Harmony——ArkTs 开发工具套件
kotlin·harmonyos
奇风3 小时前
uni-app + DevEco 鸿蒙跨平台应用开发实战1-环境安装分享
uniapp·harmonyos·鸿蒙应用开发·鸿蒙跨平台应用开发
爱笑的眼睛114 小时前
HarmonyOS Scroll滚动容器深度性能优化指南
华为·harmonyos
●VON6 小时前
Electron for HarmonyOS 开发环境搭建
javascript·electron·harmonyos
万少6 小时前
上架元服务-味寻纪 技术分享
前端·harmonyos
大雷神7 小时前
windows中flutter开发鸿蒙实操
harmonyos