HarmonyOS鸿蒙Next中web组件如何加载Html内容
HarmonyOS鸿蒙Next中web组件如何加载Html内容 Web组件如何加载html内容,是后端返回的html的内容,不是URL。
其中,html里面有类似的图片加载

import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebContent {
controller: webview.WebviewController = new webview.WebviewController();
@State htmlContent: string = `
<html>
<body>
<h1>后端返回的HTML内容</h1>
</body>
</html>
`;
build() {
Column() {
Web({ src: '', controller: this.controller })
.onControllerAttached(() => {
// 方式1:使用loadData(需编码)
this.controller.loadData(
encodeURIComponent(this.htmlContent),
"text/html",
"UTF-8"
);
// 方式2:使用loadHtml(API 9+,无需编码)
// this.controller.loadHtml(this.htmlContent);
})
}
}
}
更多关于HarmonyOS鸿蒙Next中web组件如何加载Html内容的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在鸿蒙里,Web 组件本身 没有“直接塞字符串”的 props,但官方在 WebviewController 上提供了两个等价接口,可以把后端返回的 HTML 字符串 立即渲染出来,而不用落地成文件。任选其一即可,推荐 loadData(),代码最少、最直观。
一、最快方案 —— loadData()
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct HtmlStringPage {
ctrl = new webview.WebviewController();
@State html: string = ''; // 后端返回的完整 html
aboutToAppear() {
// 模拟后台返回
this.html = `
<html>
<body>
<h1>标题</h1>
<img src="https://www.example.com/a.jpg" />
</body>
</html>`;
}
build() {
Column() {
Button('加载 HTML 字符串')
.onClick(() => {
// 第四个参数 baseUrl 可留空;图片里的 https 会自动走网络
this.ctrl.loadData(this.html, 'text/html', 'UTF-8');
})
Web({ src: '', controller: this.ctrl }) // src 先留空
.layoutWeight(1)
}
}
}
- 不用事先写文件,loadData 直接把字符串写进 Web 内核。
- 如果 html 里引用了 https:// 图片,只要设备能访问外网就能正常加载;纯内网就把图片地址换成内网地址即可。
- 字符串很大时,把第 4 个参数 baseUrl 设成 ‘data://’ 可提升解析速度 。
loadData
loadData(data: string, mimeType: string, encoding: string, baseUrl?: string, historyUrl?: string): void
加载指定的数据。
baseUrl与historyUrl同时为空的情况下:
encoding如果为非base64(包括空值),则假定数据对安全URL字符范围内的八位字节使用ASCII编码,对该范围外的八位字节使用URL的标准%xx十六进制编码。
data数据必须使用base64编码或将内容中的任何#字符编码为%23。否则#将被视为内容的结尾而剩余的文本将被用作文档片段标识符。
说明
- 若加载本地图片,可以给baseUrl或historyUrl任一参数赋值空格,详情请参考示例代码。
- 加载本地图片场景,baseUrl和historyUrl不能同时为空,否则图片无法成功加载。
- 若html中的富文本中带有注入#等特殊字符,建议将baseUrl和historyUrl两个参数的值设置为"空格"。
- 加载文字场景,需主动设置
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8">避免文本字体大小不一致。
系统能力: SystemCapability.Web.Webview.Core
参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| data | string | 是 | 按照"base64"或者"URL"编码后的一段字符串。 |
| mimeType | string | 是 | 媒体类型(MIME)。 |
| encoding | string | 是 | 编码类型,具体为"base64"或者"URL"编码。 |
| baseUrl | string | 否 | 指定的一个URL路径(“http”/“https”/“data"协议),并由Web组件赋值给window.origin。当加载大量html文件时,需设置为"data”。 |
| historyUrl | string | 否 | 用作历史记录所使用的URL。非空时,历史记录以此URL进行管理。当baseUrl为空时,此属性无效。 |
错误码:
以下错误码的详细介绍请参见Webview错误码、通用错误码。
| 错误码ID | 错误信息 |
|---|---|
| 17100001 | Init error. The WebviewController must be associated with a Web component. |
| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified. 2. Incorrect parameter types. 3.Parameter verification failed. |
示例:
baseUrl与historyUrl同时为空。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('loadData')
.onClick(() => {
try {
this.controller.loadData(
"<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>",
"text/html",
// UTF-8为charset。
"UTF-8"
);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('loadData')
.onClick(() => {
try {
this.controller.loadData(
// Coding tests通过base64编码后的字符串。
"Q29kaW5nIHRlc3Rz",
"text/html",
"base64"
);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
静静地静静地觉得好的话好多好多好多好多好多的话
我不太明白,为什么上面的html无法加载出来,但是我把span里面的样式style="color:#636366;font-size:14px;background-color:#FFFFFF;"去掉后又可以加载出来,这到底是什么原因?
是特殊字符哦!
loadData使用不同的参数会有不同的效果,如果参数不对可能会造成白屏现象。如果html中存在非法字符,例如css中的color: “#333”,有"#"的时候会加载不了,建议将baseUrl和historyUrl两个参数的值设置为"空格"即可解决问题。
web组件加载HTML格式的文本数据
1、Web组件可以通过loadData()接口实现加载HTML格式的文本数据。
当开发者不需要加载整个页面,只需要显示一些页面片段时,可通过此功能来快速加载页面,当加载大量html文件时,需设置第四个参数baseUrl为"data"。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('loadData')
.onClick(() => {
try {
// 点击按钮时,通过loadData,加载HTML格式的文本数据
this.controller.loadData(
"<html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>",
"text/html",
"UTF-8"
);
} catch (error) {
console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
}
})
// 组件创建时,加载www.example.com
Web({ src: 'www.example.com', controller: this.controller })
}
}
}
2、Web组件可以通过data url方式直接加载HTML字符串。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
htmlStr: string = "data:text/html, <html><body bgcolor=\"white\">Source:<pre>source</pre></body></html>";
build() {
Column() {
// 组件创建时,加载htmlStr
Web({ src: this.htmlStr, controller: this.controller })
}
}
}
静静地静静地觉得好的话好多好多好多好多好多的话
我不太明白,为什么上面的html无法加载出来,但是我把span里面的样式style="color:#636366;font-size:14px;background-color:#FFFFFF;"去掉后又可以加载出来,这到底是什么原因?
在HarmonyOS Next中,使用Web组件加载HTML内容主要通过loadData()方法实现。该方法允许直接加载HTML字符串,并支持设置MIME类型和编码。
示例代码:
webview.loadData(
"<html><body><h1>Hello HarmonyOS</h1></body></html>",
"text/html",
"UTF-8"
);
也可以使用loadUrl()加载本地或远程HTML文件。需注意配置网络权限和本地文件访问权限。
在HarmonyOS Next中,使用Web组件加载后端返回的HTML字符串内容,而不是通过URL,可以通过设置Web组件的htmlText属性来实现。
核心方法:使用 htmlText 属性
-
基本加载:将获取到的后端HTML字符串直接赋值给
Web组件的htmlText属性即可完成加载。// 假设 htmlContent 是从后端获取到的HTML字符串 let htmlContent: string = '<p>后端返回的HTML内容</p><img src="https://example.com/image.jpg">'; build() { Column() { // 使用 htmlText 属性加载HTML字符串 Web({ src: $rawfile('about:blank'), controller: this.controller }) .width('100%') .height('100%') .onPageEnd(() => { // 页面加载完成后,通过执行JavaScript设置HTML内容 this.controller.runJavaScript({ script: `document.write('${htmlContent}');`, callback: (result) => { // 处理回调 } }); }) } }注意:更直接的方式是在构建
Web组件时,如果已经获取到htmlContent,可以直接在src中构造一个Data URL,但使用onPageEnd回调配合runJavaScript是动态加载内容的常用方式。 -
处理图片等网络资源:当HTML中包含类似
<img src="https://...">的网络图片时,只要设备可以正常访问该URL,Web组件会像普通浏览器一样自动加载并显示这些图片,无需特殊处理。确保应用已申请必要的网络权限(ohos.permission.INTERNET)。
关键点说明:
htmlTextvssrc:htmlText属性专门用于直接加载HTML字符串内容。如果内容在应用启动时已确定,使用htmlText更直接。上述示例中使用的onPageEnd和runJavaScript方法适用于需要先加载一个空白页面再动态注入HTML内容的场景。- 网络图片:图片能否正常显示取决于网络连通性和图片服务器可达性。
Web组件内部会处理网络资源的加载。 - 性能与安全:对于大段HTML内容,直接使用
htmlText或runJavaScript是高效的。但需注意,注入的HTML/JavaScript代码应来自可信源,以防XSS等安全风险。 - 样式与交互:加载的HTML内容中的CSS样式和JavaScript脚本(如果有)在
Web组件中同样会生效并执行,这允许你展示富文本或交互式内容。
示例代码片段(直接使用htmlText的简化版):
// 构建Web组件时直接传入HTML字符串
Web({ htmlText: this.htmlContent, controller: this.controller })
.width('100%')
.height('100%')
这种方式适用于在构建时内容已就绪的情况。
总结,加载后端返回的HTML字符串到Web组件,核心是使用htmlText属性或通过runJavaScript方法动态写入document。其中的网络图片会自动加载,只要确保网络权限和连接正常即可。

