HarmonyOS鸿蒙Next中H5页面如何加载应用沙箱内图片

HarmonyOS鸿蒙Next中H5页面如何加载应用沙箱内图片

【问题现象】

H5页面使用应用沙箱路径"file://…"路径前缀的字符串直接访问应用沙箱内的图片,图片无法显示。

【背景知识】

为了提高安全性,ArkWeb内核不允许file协议或者resource协议访问URL上下文中来自跨域的请求。因此,在使用Web组件加载本地离线资源的时候,Web组件会拦截file协议和resource协议的跨域访问。

开发者使用Web组件将应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。

注册应用侧代码有两种方式,一种在Web组件初始化调用,使用javaScriptProxy()接口。另外一种在Web组件初始化完成后调用,使用registerJavaScriptProxy()接口。

【解决方案】

H5页面无法通过以"file://…"形式加载沙箱内图片,可以将图片转成base64字符串,传递给H5页面。

H5页面代码:

<html lang="zh-CN">
 <head>
     <meta charset="UTF-8"/>
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
 </head>
 <body>

 <button id="init" onclick="takePicture()">获取沙箱路径图片</button>
 <img src="" id="myImage" alt="">
 </body>
 </html>

 <script>
     function takePicture() {
         let s = 'data:image/png;base64,' + picture.chosePicture();
         console.log(s)
         document.getElementById('myImage').src =  s;
     }
 </script>

在src/main/resources/rawfile目录下存放一张图片startIcon.png:

startIcon.png

编写方法将图片转成base64:

 class Test {
   chosePicture() {
     let context = getContext(this) as common.UIAbilityContext
     let arrayBuff = context.resourceManager.getRawFileContentSync("startIcon.png")
     let base64helper = new util.Base64Helper()
     let base64string = base64helper.encodeToStringSync(arrayBuff, util.Type.MIME)
     console.debug(base64string)
     return base64string
   }
 }

将对象注入到Web端,使得前端页面可以调用应用侧函数:

 .javaScriptProxy({
   object: this.test,
   name: "picture",
   methodList: ["chosePicture"],
   controller: this.webController
 })

可以看到展示结果中图片可正常显示:

展示结果

示例代码如下:

 import { common } from '@kit.AbilityKit';
 import { util } from '@kit.ArkTS';
 import { webview } from '@kit.ArkWeb';

 @Entry
 @Component
 struct Page4 {
   webController: webview.WebviewController = new webview.WebviewController();
   @State test: Test = new Test()

   build() {
     Column() {
       Web({ src: $rawfile('shaxiangtupian.html'), controller: this.webController })
         .javaScriptProxy({
           object: this.test,
           name: "picture",
           methodList: ["chosePicture"],
           controller: this.webController
         }).height("50%")
     }
   }
 }

 class Test {
   chosePicture() {
     let context = getContext(this) as common.UIAbilityContext
     let arrayBuff = context.resourceManager.getRawFileContentSync("startIcon.png")
     let base64helper = new util.Base64Helper()
     let base64string = base64helper.encodeToStringSync(arrayBuff, util.Type.MIME)
     console.debug(base64string)
     return base64string
   }
 }

更多关于HarmonyOS鸿蒙Next中H5页面如何加载应用沙箱内图片的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中H5页面如何加载应用沙箱内图片的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS中加载应用沙箱内图片的解决方案

在HarmonyOS中,H5页面无法直接通过file://...路径加载应用沙箱内的图片。解决方案是将图片转成base64字符串,传递给H5页面。

步骤

  1. src/main/resources/rawfile目录下存放图片startIcon.png
  2. 编写方法将图片转成base64:
class Test {
  chosePicture() {
    let context = getContext(this) as common.UIAbilityContext;
    let arrayBuff = context.resourceManager.getRawFileContentSync("startIcon.png");
    let base64helper = new util.Base64Helper();
    let base64string = base64helper.encodeToStringSync(arrayBuff, util.Type.MIME);
    return base64string;
  }
}
  1. 将对象注入到Web端,使得前端页面可以调用应用侧函数:
.javaScriptProxy({
  object: this.test,
  name: "picture",
  methodList: ["chosePicture"],
  controller: this.webController
})
  1. 在H5页面中调用应用侧函数加载图片:
<button id="init" onclick="takePicture()">获取沙箱路径图片</button>
<img src="" id="myImage" alt="">
<script>
  function takePicture() {
    let s = 'data:image/png;base64,' + picture.chosePicture();
    document.getElementById('myImage').src = s;
  }
</script>

通过以上步骤,H5页面可以加载应用沙箱内的图片。

回到顶部