鸿蒙web加载本地网页资源异常

简介: 在鸿蒙NEXT Api 12中,为解决Web组件加载本地资源(如图片、CSS等)失败的问题,我们采用拦截机制。具体步骤如下:1. **替换路径**:通过正则表达式将HTML和CSS中的资源路径替换为带有标记的URL(如`http://local`),以便后续识别。2. **拦截与返回**:在资源加载时,拦截带有标记的URL,读取对应的本地文件并返回给Web组件。此过程确保了本地资源能正确加载和显示。代码实现包括路径替换、资源拦截及响应构建,确保Web页面能够顺利加载本地资源。


我们在使用web组件中发现本地资源,例如图片/Css等资源会有加载不成功的情况,web组件提供了一种拦截机制,可以在加载资源的时候拦截,并替换为本地资源,并回传给web组件,具体实现如下

核心就两步:

第一步,替换本地资源路径,相当于做了标记;

第二步,拦截标记过的资源,读取本地资源后并返回;

下面的所有代码是基于鸿蒙NEXT Api 12

@Component
struct WebPage {
// 跳转过来 传递的地址
urlPath: string = ""
controller = new webview.WebviewController()
schemeHandler: webview.WebSchemeHandler = new webview.WebSchemeHandler();
responseWeb: WebResourceResponse = new WebResourceResponse();
fileDir: string = ""

loadData() {
try {
if (this.urlPath.includes("http") == false) {
this.loadLocalUrl()
} else {
this.controller.loadUrl(this.urlPath)
}

} catch (e) {
  showShortCenterToast("加载失败")
}

}

/// 第一步,替换本地资源路径
loadLocalUrl() {
let parts = this.urlPath.split('/');
// 如果数组长度大于 1,移除最后一个元素
if (parts.length > 1) {
parts.pop();
}
// 当前H5所在文件夹的绝对路径
this.fileDir = parts.join('/')

let html = fs.readTextSync(this.urlPath)
// 要插入的指定字符串
const insertString = "http://local";
// 定义正则表达式
const regex = /src="([^"]+\.(?:png|jpg|gif))"/gi;
// 执行替换操作
const imageHtml = html.replace(regex, (_, p1: string) => {
  let content = `src="${insertString}/${p1}"`;
  return content
});

// href定义正则表达式
const cssRegex = /href="([^"]+\.(?:css|html))"/gi;
const cssHtml = imageHtml.replace(cssRegex, (_, p1: string) => {
  let content = `href="${insertString}/${p1}"`;
  return content
});
this.controller.loadData(
  cssHtml,
  'text/html',
  'UTF-8'
);

}

build() {
Web({ src: this.urlPath, controller: this.controller })
.width(FULL_WIDTH)
.mixedMode(MixedMode.All)
.layoutWeight(1)
.onControllerAttached(() => {
this.loadData()
})
.onLoadIntercept((event) => {
let url = event.data.getRequestUrl()
// 跳转拦截
if (url.toLowerCase().startsWith('http://local') && url.toLowerCase().endsWith("html/")) {
url = url.replace("http://local", "")
url = url.toUpperCase()
url = url.replace("HTML/", "html")

      const filePath = this.fileDir + "/" + url
      if (fs.accessSync(filePath)) {
        this.urlPath = filePath
        this.loadLocalUrl()
        return true
      }
    }
    return false
  })
  .onInterceptRequest((event) => {

/// 第二步,拦截对应的资源,读取本地资源后并返回
let url = event.request.getRequestUrl()
// 本地资源加载拦截
if (url.startsWith('http://local')) {
const promise: Promise = new Promise((resolve: Function, reject: Function) => {
url = url.replace("http://local", "")
const filePath = this.fileDir + "/" + url
if (fs.accessSync(filePath)) {
if (url.toLowerCase().endsWith(".png") ||
url.toLowerCase().endsWith(".jpg") ||
url.toLowerCase().endsWith(".gif") ||
url.toLowerCase().endsWith(".css")) {

            const fd = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
            // 获取文件的大小
            const stat = fs.statSync(fd.fd);
            const fileSize = stat.size;
            // 创建一个指定大小的 ArrayBuffer
            const buffer = new ArrayBuffer(fileSize);
            // 读取文件内容到 ArrayBuffer
            fs.readSync(fd.fd, buffer);
            this.responseWeb.setResponseData(buffer);
            if (url.toLowerCase().endsWith(".css")) {
              this.responseWeb.setResponseMimeType('text/css');
            } else {
              this.responseWeb.setResponseMimeType('image/*');
            }
          }
          this.responseWeb.setResponseCode(200);
          this.responseWeb.setReasonMessage('OK');
          resolve("success");
        } else {
          reject("failed")
        }
      })
      promise.then(() => {
        this.responseWeb.setResponseIsReady(true);
      })
      this.responseWeb.setResponseIsReady(false);
      return this.responseWeb;
    }
    return null

  })
  .width(FULL_WIDTH)
  .height(FULL_HEIGHT)

}
}

相关文章
|
8月前
|
前端开发 JavaScript 开发者
探索Web设计新纪元:CSS3的革新特性如何重塑我们的网页视觉体验?
【8月更文挑战第26天】随着Web技术的发展,CSS3为前端开发带来了众多激动人心的新特性,极大提升了网页设计的视觉效果与创意空间。本文通过对比CSS3与CSS2,详细介绍了CSS3在选择器增强、圆角阴影处理、渐变背景应用、转换动画实现、文字效果优化、媒体查询支持及多列布局方面的显著改进,展示了CSS3如何助力开发者打造更具吸引力和互动性的网页体验。
80 1
|
6月前
|
存储 JavaScript 关系型数据库
鸿蒙开发:实现全局异常捕获和异常查看
如何灵活的拿到错误信息后,执行我们想要的逻辑,也是自研的一个诉求,比如全局监听到异常后,重启应用,或者上传到自己的服务器,或者可以在应用内查看等等,实现一个全局异常捕获,确实有很多的有用之处。
113 3
鸿蒙开发:实现全局异常捕获和异常查看
|
5月前
|
Java Maven Spring
Java Web 应用中,资源文件的位置和加载方式
在Java Web应用中,资源文件如配置文件、静态文件等通常放置在特定目录下,如WEB-INF或classes。通过类加载器或Servlet上下文路径可实现资源的加载与访问。正确管理资源位置与加载方式对应用的稳定性和可维护性至关重要。
126 7
|
6月前
|
JavaScript API 开发工具
(H5-Web3D-ThreeJS)在网页三维CAD中绘制窗户模型
本文介绍了如何使用mxcad3d在网页中创建一个简单的三维窗户模型。通过官方教程搭建环境,编写绘制窗户模型的代码,并在点击按钮后展示模型效果。最终模型包括窗框和玻璃部分,具备丰富的三维建模功能和便捷的API支持。
|
7月前
|
小程序 前端开发 中间件
ThinkPHP 配置跨域请求,使用TP的内置跨域类配置,小程序和web网页跨域请求的区别及格式说明
本文介绍了如何在ThinkPHP框架中配置跨域请求,使用了TP内置的跨域类`\think\middleware\AllowCrossDomain::class`。文章还讨论了小程序和web网页在跨域请求格式上的区别,并提供了解决方案,包括修改跨域中间件源码以支持`Origin`和`token`。此外,还介绍了微信小程序跨域请求的示例和web网页前端发送Axios跨域请求的请求拦截器配置。
ThinkPHP 配置跨域请求,使用TP的内置跨域类配置,小程序和web网页跨域请求的区别及格式说明
|
6月前
|
Web App开发 前端开发 网络性能优化
Web网页端IM产品RainbowChat-Web的v7.2版已发布
RainbowChat-Web是一套Web网页端IM系统,是RainbowChat的姊妹系统(RainbowChat是一套基于开源IM聊天框架 MobileIMSDK (Github地址) 的产品级移动端IM系统)。
85 1
|
7月前
|
SQL 安全 搜索推荐
Web安全-伪静态网页
Web安全-伪静态网页
88 3
|
8月前
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
330 0
|
8月前
|
安全 开发者 UED
|
8月前
【Azure 应用服务】Web.config中设置域名访问限制,IP地址限制访问特定的页面资源 (Rewrite)
【Azure 应用服务】Web.config中设置域名访问限制,IP地址限制访问特定的页面资源 (Rewrite)
102 0