核心是白名单机制而非属性注解——需显式配置允许的HTML标签及属性,通过DOMPurify等工具或自研清洗函数在XSS过滤环节执行;UEditor等编辑器通过whitList对象实现,如'a': ['href','target'];contenteditable和data-*不参与清洗。

富文本编辑器解析逻辑中,控制哪些 HTML 标签可放行,核心不是靠“属性注解”,而是靠白名单机制——即在内容输入后、存储或渲染前,明确列出允许保留的标签及对应属性,其余一律剥离。所谓“属性注解”(如 Java 的 @AllowedTag)在前端 HTML 解析中并不存在,也不被浏览器支持;真正起作用的是配置化的过滤规则。
白名单必须显式声明标签与属性
不能依赖注释、data-* 属性或自定义标记来“标注”哪些标签合法。浏览器不识别这些,解析器也不会自动读取它们做判断。正确做法是:在 XSS 过滤环节(如使用 DOMPurify、UEditor 白名单、或自研清洗函数)中硬编码或配置一个允许列表。例如:
- 允许的标签:<p>、<h2>、<ul>、<li>、<strong>、<em>、<a>、<img>
- 允许的属性:<a> 只留 href、target;<img> 只留 src、alt、width、height;禁止 style、onerror、javascript: 等危险属性
UEditor 等成熟编辑器用 whitList 配置实现
像 UEditor 就直接提供 whitList 配置项,本质就是 JS 对象,键为标签名,值为该标签允许的属性数组。例如:
whitList: {
'a': ['href', 'target', 'class'],
'img': ['src', 'alt', 'width', 'height'],
'p': ['class', 'style'], // 若需限制 style,还得配合 CSS 白名单
'span': [] // 允许 span 标签,但不允许任何属性(常用于纯语义包裹)
}这个配置在初始化编辑器时传入,后续所有粘贴、插入、导出的内容都会按此规则清洗,不是靠 HTML 里写个注释就能绕过。
立即学习“前端免费学习笔记(深入)”;
自研清洗逻辑中,用 tagName + hasAttribute 判断
如果不用现成库,自己写 DOM 清洗函数,关键逻辑是遍历所有节点,逐个检查:
- 若
node.tagName.toLowerCase()不在白名单数组中 → 移除或转为纯文本 - 若在白名单中,再遍历其
node.attributes,对每个 attribute 检查是否属于该标签允许的属性列表 - 特别注意:
style属性需二次校验(只放行 color、font-size 等安全值),href要验证协议(仅允许 http/https/mailto)
别把 contenteditable 或 data-* 当成“放行标记”
有人误以为给某个 <div contenteditable="false"> 或 <p data-allowed="true"> 就能告诉解析器“这个可以留”,这是无效的。contenteditable 控制编辑行为,data-* 是自定义数据容器,二者都不参与 HTML 输出清洗。解析器只认结构和配置,不读语义注解。



















