Flutter for OpenHarmony:html_unescape 安全解码 HTML 实体字符,从网页抓取数据到友好展示(文本转义处理) 深度解析与鸿蒙适配指南
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net
前言
当我们从网页抓取数据(爬虫),或者接收富文本编辑器生成的后端接口时,常常会遇到像 <、'、 这样的 HTML 实体字符。如果直接显示在 UI 上,不仅丑陋,而且难以阅读。
html_unescape 是一个专为 Dart 设计的小型库,它能快速、准确地将这些编码后的实体字符还原为原始文本(如 <、'、空格),兼容所有 HTML5 标准实体。
一、概念介绍/原理解析
1.1 基础概念
- HTML Entity: 为了在 HTML 中显示保留字符(如
<),必须使用转义序列(&...;)。 - Decoded Text: 还原后的字符,直接供人类阅读。
- Named Entity: 如
©->©。 - Numeric Entity: 如
©->©。
调用 HtmlUnescape
解码渲染
"Hello" & World (编码串)
核心解析逻辑
Hello & World (还原文本)
&😀 (数字实体)
😀 (表情符号)
1.2 进阶概念
虽然 flutter_html 等渲染库也能处理,但它主要用于渲染整个 HTML。若只需处理单行文本(如新闻标题),html_unescape 更轻量。
二、核心 API/组件详解
2.1 基础用法
最简单的字符串解码。
import'package:html_unescape/html_unescape.dart';voidmain(){final unescape =HtmlUnescape();// 基础符号print(unescape.convert('Flutter & Dart: The "Secret" to 100% OHOS Fix!'));// 中文乱码修复 (如果是以实体形式存在)print(unescape.convert('中文'));// 输出: 中文}
2.2 小技巧
由于创建 HtmlUnescape 对象需要加载映射表(虽小但非零开销),建议在单例或静态变量中复用它。
classTextUtils{staticfinal _unescape =HtmlUnescape();staticStringclean(String input)=> _unescape.convert(input);}三、常见应用场景
3.1 场景 1:RSS 阅读器
RSS Feed 中的标题和摘要通常包含大量的 HTML 实体,需解码后展示。
// RSS 解析器通常返回已解码的文本,但如果返回 raw XML:final title =parse(item.title).text;// 或者final cleanTitle = unescape.convert(item.rawTitle);
3.2 场景 2:搜索结果高亮
搜索引擎返回的摘要中,关键字被 <em> 包裹,需提取纯文本或自行构建高亮。
// 原始: "Hello <em>World</em>"// 解码后: "Hello <em>World</em>" (注意 unescape 只处理实体,不处理标签)// 若要处理实体如 "<em>" -> "<em>"3.3 场景 3:聊天消息
防止用户输入被解释为 HTML(XSS),后端转义后,前端需在特定安全上下文中还原(如代码块内)。
classCodeBlockextendsStatelessWidget{finalString rawCode;// 后端返回如 "print("Hi")"@overrideWidgetbuild(BuildContext context){returnText(HtmlUnescape().convert(rawCode));// 显示 print("Hi")}}四、OpenHarmony 平台适配
4.1 纯 Dart 实现
无平台依赖,OpenHarmony 完美支持。
五、完整示例代码
本示例模拟一个从网络获取新闻列表的场景,原始数据充斥着实体字符,App 将其清洗后展示。
import'package:flutter/material.dart';import'package:html_unescape/html_unescape.dart';classNewsFullDemoPageextendsStatelessWidget{constNewsFullDemoPage({super.key});@overrideWidgetbuild(BuildContext context){final unescape =HtmlUnescape();final articles =[{'t':'Breaking & Hot: OHOS 5.0 Release','s':'New <Features> inside!'},{'t':'Café Life: Best Coffee ☕','s':'Visit us © 2026'},];returnScaffold( appBar:AppBar(title:constText('实战:纯净新闻阅读')), body:ListView.separated( itemCount: articles.length, separatorBuilder:(_, __)=>constDivider(), itemBuilder:(context, index){final a = articles[index];returnListTile( title:Text(unescape.convert(a['t']!), style:constTextStyle(fontWeight:FontWeight.bold)), subtitle:Text(unescape.convert(a['s']!)), trailing:constIcon(Icons.navigate_next),);},),);}}
六、总结
html_unescape 是处理 Web 数据的必备小工具。
最佳实践:
- 按需使用:不要对所有文本都调用,不仅浪费性能,还可能破坏原本就是想显示
&的意图。 - 安全性:解码后的文本若直接插入 HTML(如 WebView),务必小心 XSS 攻击。通常在 Flutter Widget (
Text) 中显示是安全的。