写点什么

鸿蒙网络编程系列 20- 解决 web 组件加载网页白屏示例

作者:长弓三石
  • 2024-10-22
    广东
  • 本文字数:2872 字

    阅读完需:约 9 分钟

1. web 组件加载网页白屏表现

鸿蒙系统提供了 web 组件,可以在 APP 里内嵌该组件显示网页信息,但是,很多开发者反应一种比较奇特的情况,就是在加载的网页里,如果含有字符 #的话,就会出现白屏,或者是 #后的内容无法显示。当然,web 组件加载网页的方式比较多,在上文鸿蒙网络编程系列18-Web组件加载网页的四种方式示例里已经介绍了,这种出现白屏的情况,一般都是因为使用了 WebviewController 的 loadData 方法进行加载。

2. 白屏原因分析

WebviewController 可以通过 loadUrl 或者 loadData 进行内容的加载,但是,在 WebviewController 的底层,调用的方法是不一样的,底层代码如下所示:


ErrCode WebviewController::LoadUrl(std::string url, std::map<std::string, std::string> httpHeaders){    auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_);    if (!nweb_ptr) {        return INIT_ERROR;    }    return nweb_ptr->Load(url, httpHeaders);}
ErrCode WebviewController::LoadData(std::string data, std::string mimeType, std::string encoding, std::string baseUrl, std::string historyUrl){ auto nweb_ptr = NWebHelper::Instance().GetNWeb(nwebId_); if (!nweb_ptr) { return INIT_ERROR; } if (baseUrl.empty() && historyUrl.empty()) { return nweb_ptr->LoadWithData(data, mimeType, encoding); } return nweb_ptr->LoadWithDataAndBaseUrl(baseUrl, data, mimeType, encoding, historyUrl);}
复制代码


也就是说,问题是出在底层的组件上,鸿蒙系统对此也是爱莫能助。在调用 LoadWithData(data, mimeType, encoding)或者 LoadWithDataAndBaseUrl(baseUrl, data, mimeType, encoding, historyUrl)时,需要注意一点,就是对于 data 中的内容,如果含有符号 #的话,被认为是需要转义的,也就是说要转换成 %23,否则就会出现显示问题。如果你不想转义,其实也有办法,就是把 data 中的内容进行 base64 编码,然后把 encoding 参数设置为“base64”就可以了。需要注意的是,这里要小写,不能写成 Base64

3. 白屏解决方式示例

本示例将演示 html 内容白屏显示以及解决白屏问题的示例,运行后的初始界面如下所示:



下面详细介绍创建该应用的步骤。


步骤 1:创建 Empty Ability 项目。


步骤 2:在 module.json5 配置文件加上对权限的声明:


"requestPermissions": [      {        "name": "ohos.permission.INTERNET"      }    ]
复制代码


这里添加了获取互联网信息的权限。


步骤 3:在 Index.ets 文件里添加如下的代码:


import util from '@ohos.util';import web_webview from '@ohos.web.webview'
@Entry@Componentstruct Index { //要加载的内容 @State webContent: string = `<!DOCTYPE html><html><body style="font-size: large;text-align: center;"> <div>前面的内容#后面的内容,咋区别对待呢!</div></body></html>` scroller: Scroller = new Scroller() contentScroller: Scroller = new Scroller() controller: web_webview.WebviewController = new web_webview.WebviewController()
build() { Row() { Column() { Text("HTML包含特殊字符示例") .fontSize(14) .fontWeight(FontWeight.Bold) .width('100%') .textAlign(TextAlign.Center) .padding(10)
Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text("HTML内容:") .fontSize(14) .width(100) .flexGrow(1)
Button("加载") .onClick(() => { this.controller.loadData(this.webContent, "text/html", "utf-8") }) .width(80) .fontSize(14)
Button("Base64加载") .onClick(() => { let base64Content = string2Base64(this.webContent) this.controller.loadData(base64Content, "text/html", "base64") }) .width(120) .fontSize(14) } .width('100%') .padding(5)
Scroll(this.contentScroller) { TextArea({ text: this.webContent }) .onChange((value) => { this.webContent = value }) .backgroundColor(0xffffee) .width('100%') .fontSize(11) } .align(Alignment.Top) .backgroundColor(0xeeeeee) .height(120) .scrollable(ScrollDirection.Vertical) .scrollBar(BarState.On) .scrollBarWidth(20)
Scroll(this.scroller) { Web({ src: "about:blank", controller: this.controller }) .padding(10) .width('100%') .backgroundColor(0xeeeeee) } .align(Alignment.Top) .backgroundColor(0xeeeeee) .height(300) .flexGrow(1) .scrollable(ScrollDirection.Vertical) .scrollBar(BarState.On) .scrollBarWidth(20) } .width('100%') .justifyContent(FlexAlign.Start) .height('100%') } .height('100%') }}
//对字符串base64编码function string2Base64(src: string) { let textEncoder = new util.TextEncoder(); let encodeValue = textEncoder.encodeInto(src)
let tool = new util.Base64Helper() return tool.encodeToStringSync(encodeValue)}
复制代码


步骤 4:编译运行,可以使用模拟器或者真机。


步骤 5:单击“加载”按钮,截图如下所示:



可以看到,只显示了符号 #前面的内容。


步骤 6:单击“Base64 加载”按钮,截图如下所示:



可以看到,显示了完整的内容。

4. 加载功能分析

在第一种加载方式中,代码如下:


this.controller.loadData(this.webContent, "text/html", "utf-8")
复制代码


直接加载了输入控件中的内容,所以显示有问题。


第二种方式下,代码如下:


let base64Content = string2Base64(this.webContent)              this.controller.loadData(base64Content, "text/html", "base64")
复制代码


这里对于加载的内容进行了 base64 编码,所以可以正常显示。


base64 编码的函数如下所示:


//对字符串base64编码function string2Base64(src: string) {  let textEncoder = new util.TextEncoder();  let encodeValue = textEncoder.encodeInto(src)
let tool = new util.Base64Helper() return tool.encodeToStringSync(encodeValue)}
复制代码


(本文作者原创,除非明确授权禁止转载)


本文源码地址:


https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/web/WebviewLoaddata


本系列源码地址:


https://gitee.com/zl3624/harmonyos_network_samples


发布于: 刚刚阅读数: 3
用户头像

长弓三石

关注

还未添加个人签名 2024-10-16 加入

二十多年软件开发经验的软件架构师,华为HDE、华为云HCDE、仓颉语言CLD、CCS,著有《仓颉语言网络编程》、《仓颉语言元编程》、《仓颉语言实战》、《鲲鹏架构入门与实战》等书籍,清华大学出版社出版。

评论

发布
暂无评论
鸿蒙网络编程系列20-解决web组件加载网页白屏示例_DevEco Studio_长弓三石_InfoQ写作社区