鸿蒙 Web组件加载:网络、本地、HTML文本
在HarmonyOS应用开发中,Web组件是展示网页内容的核心组件。本文将全面解析Web组件的各种页面加载方式,涵盖网络页面、本地页面、HTML文本数据等多种场景。
·
本文同步发表于 微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
Web组件支持加载方式:
| 加载方式 | 适用场景 | 特点 |
|---|---|---|
| 网络页面 | 在线内容、Web应用 | 需要网络权限,支持动态加载 |
| 本地页面 | 离线内容、启动页 | 加载速度快,无网络依赖 |
| HTML文本 | 动态内容、富文本 | 无需文件,直接加载HTML字符串 |
二、加载网络页面
2.1 网络页面加载
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebNetworkPage {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
// 1. 初始加载网络页面
Web({
src: 'https://www.example.com',
controller: this.controller
})
}
}
}
2.2 动态切换网络页面
@Entry
@Component
struct DynamicWebPage {
controller: webview.WebviewController = new webview.WebviewController();
// 重要:src参数不能通过@State变量动态更改!
// 必须使用loadUrl()方法
build() {
Column() {
// 切换页面的按钮
Button('加载新页面')
.onClick(() => {
try {
// 使用loadUrl动态加载新页面
this.controller.loadUrl('https://www.example1.com');
} catch (error) {
const err = error as BusinessError;
console.error(`加载失败!错误码: ${err.code}, 消息: ${err.message}`);
}
})
.margin(10)
// 显示Web组件
Web({
src: 'https://www.example.com', // 初始页面
controller: this.controller
})
}
}
}
2.3 网络权限配置
必须在module.json5中配置网络访问权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
三、加载本地页面
3.1 加载rawfile目录下的文件
项目结构
src/
├── main/
│ ├── ets/
│ │ └── pages/
│ │ └── WebLocalPage.ets
│ └── resources/
│ └── rawfile/
│ ├── local.html
│ ├── local1.html
│ └── styles.css
代码实现
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct WebLocalPage {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
// 切换本地页面的按钮
Button('切换到local1.html')
.onClick(() => {
try {
// 使用$rawfile加载rawfile目录下的文件
this.controller.loadUrl($rawfile('local1.html'));
} catch (error) {
const err = error as BusinessError;
console.error(`加载失败!错误码: ${err.code}, 消息: ${err.message}`);
}
})
.margin(10)
// 初始加载本地页面
Web({
src: $rawfile('local.html'), // 加载rawfile/local.html
controller: this.controller
})
}
}
}
本地HTML文件示例
local.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- 加载本地CSS文件 -->
<link rel="stylesheet" href="resource://rawfile/styles.css">
</head>
<body>
<h1>欢迎使用本地页面</h1>
<p>这是一个本地HTML文件示例</p>
<button onclick="showAlert()">点击测试</button>
<script>
function showAlert() {
alert('本地页面JavaScript正常运行!');
}
</script>
</body>
</html>
styles.css:
body {
font-family: 'Arial', sans-serif;
padding: 20px;
background-color: #f5f5f5;
}
h1 {
color: #333;
text-align: center;
}
3.2 加载沙箱路径下的文件
全局上下文管理类
// GlobalContext.ets - 全局状态管理
export class GlobalContext {
private constructor() {}
private static instance: GlobalContext;
private _objects = new Map<string, Object>();
// 获取单例实例
public static getContext(): GlobalContext {
if (!GlobalContext.instance) {
GlobalContext.instance = new GlobalContext();
}
return GlobalContext.instance;
}
// 获取对象
getObject(key: string): Object | undefined {
return this._objects.get(key);
}
// 设置对象
setObject(key: string, objectClass: Object): void {
this._objects.set(key, objectClass);
}
}
在Ability中设置沙箱路径
// EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { GlobalContext } from './GlobalContext';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
// 保存沙箱路径到全局上下文
GlobalContext.getContext().setObject("filesDir", this.context.filesDir);
console.info("沙箱路径: " + GlobalContext.getContext().getObject("filesDir"));
// 可选:创建并写入测试HTML文件
this.createTestHtmlFile();
}
// 创建测试HTML文件
private async createTestHtmlFile() {
const fs = this.context.filesDir;
const filePath = fs + '/index.html';
const htmlContent = `
<!DOCTYPE html>
<html>
<body>
<h1>沙箱中的HTML文件</h1>
<p>这是一个存储在应用沙箱中的文件</p>
</body>
</html>`;
// 使用文件管理API写入文件
// 实际开发中需要使用@kit.FileManagementKit
}
}
加载沙箱文件
import { webview } from '@kit.ArkWeb';
import { GlobalContext } from './GlobalContext';
@Entry
@Component
struct SandboxWebPage {
controller: webview.WebviewController = new webview.WebviewController();
// 构建沙箱文件URL
private sandboxUrl: string = '';
aboutToAppear() {
// 获取沙箱路径并构建文件URL
const filesDir = GlobalContext.getContext().getObject('filesDir') as string;
if (filesDir) {
this.sandboxUrl = 'file://' + filesDir + '/index.html';
console.info('沙箱文件URL: ' + this.sandboxUrl);
}
}
build() {
Column() {
// 加载沙箱中的文件,必须开启fileAccess权限
Web({
src: this.sandboxUrl,
controller: this.controller
})
.fileAccess(true) // 开启文件访问权限
}
}
}
四、加载HTML格式的文本数据
4.1 使用loadData()方法
适用于动态生成或从网络获取的HTML内容。
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct HtmlTextPage {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('加载HTML文本')
.onClick(() => {
try {
// 定义HTML内容
const htmlContent = `
<html>
<head>
<style>
body {
font-family: sans-serif;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
h1 { text-align: center; }
.card {
background: rgba(255,255,255,0.1);
padding: 20px;
border-radius: 10px;
margin: 20px 0;
}
</style>
</head>
<body>
<h1>动态HTML内容</h1>
<div class="card">
<h3>欢迎使用</h3>
<p>这是通过loadData加载的动态HTML内容</p>
<p>当前时间: ${new Date().toLocaleString()}</p>
</div>
</body>
</html>`;
// 加载HTML文本数据
this.controller.loadData(
htmlContent, // HTML字符串
'text/html', // MIME类型
'UTF-8' // 编码格式
);
} catch (error) {
const err = error as BusinessError;
console.error(`加载失败!错误码: ${err.code}, 消息: ${err.message}`);
}
})
.margin(10)
// 初始显示一个页面
Web({
src: $rawfile('default.html'),
controller: this.controller
})
}
}
}
4.2 使用data URL方式
更简洁的直接加载方式。
@Entry
@Component
struct DataUrlWebPage {
controller: webview.WebviewController = new webview.WebviewController();
// 直接使用data URL
htmlStr: string = 'data:text/html,' + encodeURIComponent(`
<html>
<body style="background:#f0f0f0;padding:20px;">
<h2 style="color:#333;">Data URL加载示例</h2>
<p>这是通过data URL直接加载的HTML内容</p>
<ul>
<li>优点:无需额外文件</li>
<li>缺点:URL长度有限制</li>
</ul>
</body>
</html>`);
build() {
Column() {
Web({
src: this.htmlStr,
controller: this.controller
})
}
}
}
4.3 处理大量HTML内容
当加载大量HTML时,建议设置baseUrl参数:
// 加载大量HTML时使用
this.controller.loadData(
largeHtmlContent,
'text/html',
'UTF-8',
'data' // baseUrl参数,避免URL过长问题
);
五、使用resource协议加载资源
5.1 resource协议
resource://协议专门用于访问应用资源目录中的文件,是加载本地资源的推荐方式。
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct ResourceWebPage {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Button('加载resource资源')
.onClick(() => {
try {
// 使用resource协议加载rawfile目录下的文件
this.controller.loadUrl('resource://rawfile/page2.html');
} catch (error) {
console.error(`加载失败!错误码: ${error.code}, 消息: ${error.message}`);
}
})
.margin(10)
// 初始使用resource协议加载
Web({
src: 'resource://rawfile/page1.html',
controller: this.controller
})
}
}
}
5.2 HTML中引用本地资源
在HTML文件中,可以使用resource://协议引用CSS、JS、图片等本地资源:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- 加载本地CSS -->
<link rel="stylesheet" href="resource://rawfile/styles/main.css">
<!-- 加载本地JavaScript -->
<script src="resource://rawfile/scripts/app.js"></script>
</head>
<body>
<h1>使用resource协议</h1>
<!-- 加载本地图片 -->
<img src="resource://rawfile/images/logo.png" alt="Logo">
<!-- 加载本地字体 -->
<style>
@font-face {
font-family: 'CustomFont';
src: url('resource://rawfile/fonts/custom.ttf');
}
body {
font-family: 'CustomFont', sans-serif;
}
</style>
</body>
</html>
六、总结
| 特性 | 网络页面 | 本地页面(rawfile) | 本地页面(沙箱) | HTML文本 |
|---|---|---|---|---|
| 加载速度 | 依赖网络 | 快速 | 快速 | 最快 |
| 网络需求 | 必需 | 无需 | 无需 | 无需 |
| 内容更新 | 实时更新 | 需发版更新 | 运行时可更新 | 动态生成 |
| 安全性 | 有风险 | 安全 | 安全 | 安全 |
| 适用场景 | 在线内容 | 静态资源 | 动态生成文件 | 富文本展示 |
常用路径写法
// 正确的路径写法
const paths = {
// 网络路径
network: 'https://www.example.com',
// 本地rawfile路径
localRawfile: $rawfile('page.html'),
localResource: 'resource://rawfile/page.html',
// 沙箱路径
sandbox: 'file:///data/storage/el2/base/haps/entry/files/page.html',
};
更多推荐
所有评论(0)