rich-text 不负责提取纯文本,它只渲染;其 nodes 是内部中间结构,语义失真、节点被拆分合并、嵌套受限,直接遍历会漏内容错顺序;推荐 h5/app 用 domparser + textcontent(需 xss 过滤),小程序用正则兜底并解码实体。

rich-text 不负责提取纯文本,它只渲染——想从 HTML 字符串里干净地抽文字,得自己写过滤逻辑或用可靠解析器。
为什么不能直接用 rich-text 的 nodes 提取文本
rich-text 的 nodes 是渲染用的中间结构,不是标准 DOM;它经过 uni-app 内部转换,丢失了原始语义层级,且 text 节点可能被拆分、合并或截断(尤其含 emoji 或 Unicode 组合字符时)。直接遍历 nodes 数组取 text 字段,会漏内容、错顺序、丢换行。
- 比如
<p>hello<br>world</p>→nodes可能变成[{type:'text',text:'helloworld'}],<br>信息彻底消失 - 嵌套标签如
<strong><em>abc</em></strong>在nodes中可能扁平化为单个text节点,无法还原原始结构 - 小程序平台下,
nodes还受平台限制(微信小程序最多支持 5 层嵌套,超深结构直接丢子节点)
推荐做法:用 DOMParser + textContent 做轻量解析
在 H5 和 App 端可用原生 DOMParser,安全、准确、不依赖第三方库。小程序端需降级为正则兜底(但仅限简单场景)。
- H5 / App:创建临时 DOM,调用
document.createElement('div').innerHTML = htmlString,再取element.textContent—— 注意要先做基础 XSS 过滤(删掉<script></script>、<style></style>、onerror=等) - 微信/支付宝小程序:不支持
DOMParser,改用正则粗筛:htmlString.replace(/]*>/g, '').replace(/\s+/g, ' ').trim(),但会把 、< 等实体当普通字符保留,需额外解码 - 统一处理换行:原始 HTML 的
<br>、<p></p>、<div> 在纯文本中应转为空格或换行符,正则无法区分,建议用 <code>DOMParser后手动遍历节点补逻辑mp-html 或 u-parse 的
getText方法不可信这两个库主打渲染,不是文本提取工具。它们的
getText或类似 API 实际是遍历自身生成的虚拟节点树,和rich-text的nodes一样存在结构失真问题——比如 mp-html 会把<img alt="cat">的alt当作文本提取,但 u-parse 默认忽略alt;同一份 HTML,两库输出的纯文本长度可能差 20%+。- 别依赖
mp-html.parse(html).getText()做数据清洗或搜索索引,结果不稳定 - 若已引入 mp-html,可复用其 parser 输出的 AST,但需自己写递归遍历逻辑,跳过
tag === 'img'、tag === 'video'等非文本节点,并处理text、children、attrs.alt等字段 - u-parse 没公开 AST 访问接口,强行读取内部
_tree属性属于黑盒调用,升级后极易崩
真正可靠的纯文本提取,必须和渲染链路解耦——要么用 DOM 环境走标准路径,要么用带 HTML 实体解码能力的专用 parser(如
he库 + 正则组合),别指望富文本渲染组件顺带帮你干活。最易被忽略的是:不同平台对空格、换行、Unicode 零宽字符的处理差异,测试时一定要用真实后台返回的 HTML,而不是手工写的简化样例。 - 别依赖











