HarmonyOS鸿蒙Next中Web组件的webviewController.loadData加载HTML片段失败问题怎么解决

HarmonyOS鸿蒙Next中Web组件的webviewController.loadData加载HTML片段失败问题怎么解决

【问题现象】

使用Web组件时候,加载rawfile里的HTML文件显示正常,但是使用WebviewController.loadData加载时白屏,排查代码时发现去除<style>标签内容就显示正常,但是这种方式会影响到页面样式。

本地HTML文件:

<head>
  <style>
    a {
      text-decoration: none;
      color: #007aff;
    }
  </style>
</head>
<body>
  <span>
    >欢迎使用大润发优鲜!
    <br />请您务必在使用大润发优鲜服务前,认真阅读大润发优鲜
    <a href="https://help.rt-mart.com/html/yx/yxyhxy.html">《用户协议》</a>
    和
    <a href="https://help.rt-mart.com/html/yx/yxyszc.html">《隐私政策》</a>。
    <br />为便于您更直观了解我们如何保护您的个人信息,特向您说明如下:
    <br />1、为提供服务收集使用的个人信息:.....。您可以通过我们产品中提供的功能设置进行上述操作。
  </span>
</body>

【背景知识】

  1. Arkts相关API介绍:@ohos.web.webview提供Web控制能力,Web组件提供网页显示的能力,loadData用于加载指定的数据。官方文档:Web
  2. encodeURIComponent介绍:**encodeURIComponent()**函数是JavaScript标准内置对象,通过将特定字符的每个实例替换成代表字符的UTF-8编码的一个、两个、三个或四个转义序列来编码URI(只有由两个“代理”字符组成的字符会被编码为四个转义序列)。

【定位思路】

问题中有提到,去除<style>标签内容就显示正常,那么问题极有可能出在<style>标签内容上。分别将a标签的两个属性注释掉后运行程序进行排查,最后发现问题出在color这一行。那么具体的问题点是什么呢?仔细查看loadData的官方文档:data数据必须使用base64编码或将内容中的任何#字符编码为%23,否则#将被视为内容的结尾而剩余的文本将被用作文档片段标识符。可以得知是#符号导致了问题。

【解决方案】

使用encodeURIComponent函数将html内容编码,#符被编码为%23后,loadData将正常加载html内容。示例代码如下:

import { webview } from '@kit.ArkWeb'
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
@Component
struct Index {
  @State btnText: string = '点击加载'
  private webviewController: WebviewController = new webview.WebviewController

  build() {
    Column() {
      Button(this.btnText)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          try {
            // 点击按钮时,通过loadData,加载HTML格式的文本数据
            this.webviewController.loadData(
              encodeURIComponent(`
              <head>
                <style> a { text-decoration: none; color: #007aff; } </style>
              </head>
              <body>
                <span>欢迎使用大润发优鲜! 
                  <br/>
                  请您务必在使用大润发优鲜服务前,认真阅读大润发优鲜 
                  <a href="https://help.rt-mart.com/html/yx/yxyhxy.html">《用户协议》</a> 
                  和 
                  <a href="https://help.rt-mart.com/html/yx/yxyszc.html">《隐私政策》</a>。 
                  <br/>
                  为便于您更直观了解我们如何保护您的个人信息,特向您说明如下: 
                  <br/>
                  1、为提供服务收集使用的个人信息:.....。您可以通过我们产品中提供的功能设置进行上述操作。 
                </span>
              </body>
              `),
              "text/html",
              "UTF-8",
            );
          } catch (error) {
            let e: BusinessError = error as BusinessError;
            console.error(`ErrorCode: ${e.code}, Message: ${e.message}`);
          }
        })
      Web({
        src: 'https://developer.huawei.com/consumer/cn/',
        controller: this.webviewController,
      })
        .layoutWeight(1)
    }
    .width('100%')
  }
}

更多关于HarmonyOS鸿蒙Next中Web组件的webviewController.loadData加载HTML片段失败问题怎么解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中Web组件的webviewController.loadData加载HTML片段失败问题怎么解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


使用encodeURIComponent函数将HTML内容编码

使用encodeURIComponent函数将HTML内容编码,确保#符号被编码为%23,从而避免loadData#视为内容结尾。示例代码如下:

import { webview } from '@kit.ArkWeb'
import { BusinessError } from '@kit.BasicServicesKit'

@Entry
@Component
struct Index {
  @State btnText: string = '点击加载'
  private webviewController: WebviewController = new webview.WebviewController

  build() {
    Column() {
      Button(this.btnText)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          try {
            this.webviewController.loadData(
              encodeURIComponent(`
              <head>
                <style> a { text-decoration: none; color: #007aff; } </style>
              </head>
              <body>
                <span>欢迎使用大润发优鲜! 
                  <br/>
                  请您务必在使用大润发优鲜服务前,认真阅读大润发优鲜 
                  <a href="https://help.rt-mart.com/html/yx/yxyhxy.html">《用户协议》</a> 
                  和 
                  <a href="https://help.rt-mart.com/html/yx/yxyszc.html">《隐私政策》</a>。 
                  <br/>
                  为便于您更直观了解我们如何保护您的个人信息,特向您说明如下: 
                  <br/>
                  1、为提供服务收集使用的个人信息:.....。您可以通过我们产品中提供的功能设置进行上述操作。 
                </span>
              </body>
              `),
              "text/html",
              "UTF-8",
            );
          } catch (error) {
            let e: BusinessError = error as BusinessError;
            console.error(`ErrorCode: ${e.code}, Message: ${e.message}`);
          }
        })
      Web({
        src: 'https://developer.huawei.com/consumer/cn/',
        controller: this.webviewController,
      })
        .layoutWeight(1)
    }
    .width('100%')
  }
}
回到顶部