
本文讲解为何不应使用正则表达式清理 html,推荐使用专业 html 清洗库(如 dompurify 或 sanitize-html),并提供完整、安全的前后端协同处理方案。
在 Web 开发中,常需对用户输入的 HTML 内容进行“白名单过滤”——即仅保留 、、 等少数可信标签,移除所有其他标签(含其属性、自闭合标签及注释等)。看似简单的需求,绝不可依赖正则表达式实现。
你尝试的正则 /]*>/g 存在根本性缺陷:
- 无法正确处理嵌套、转义、HTML 实体(如 ;
- 对
- 遇到不规范 HTML(如缺少闭合、大小写混用、空格/换行异常)极易崩溃或漏匹配;
-
存在严重 XSS 安全风险:攻击者可构造 javascript:alert(1)"> 或
绕过简单正则。
✅ 正确做法:使用经过严格审计的专业 HTML 清洗库。
✅ 推荐方案(前端)
DOMPurify(轻量、高性能、主动维护):
立即学习“前端免费学习笔记(深入)”;
npm install dompurify
import DOMPurify from 'dompurify';
const allowedTags = ['a', 'b', 'i', 's', 'u', 'sup', 'sub', 'strong', 'cite', 'code', 'del', 'em'];
const config = {
ALLOWED_TAGS: allowedTags,
ALLOWED_ATTR: ['href', 'title'], // 可选:限制允许的属性
FORBID_TAGS: ['script', 'style'], // 显式禁止高危标签
};
const input = '@@##@@TestPassedwithout any errorsclick here';
const clean = DOMPurify.sanitize(input, config);
console.log(clean);
// → "TestPassedwithout any errorsclick here"✅ 推荐方案(后端 —— 必须!)
前端净化仅用于用户体验优化,不能替代服务端校验。攻击者可绕过前端 JS 直接发送恶意请求。
-
Node.js:使用 sanitize-html(支持深度配置):
const sanitizeHtml = require('sanitize-html'); const clean = sanitizeHtml(input, { allowedTags: allowedTags, allowedAttributes: { a: ['href', 'title'] }, disallowedTagsMode: 'recursiveEscape' // 移除非法标签并转义其内容 }); -
PHP(Symfony):启用内置 HTML Sanitizer:
use Symfony\Component\HtmlSanitizer\HtmlSanitizer; use Symfony\Component\HtmlSanitizer\Rule\TextRule; $sanitizer = new HtmlSanitizer([ new TextRule(['a','b','i','u','strong','em']), // 白名单 ]); $clean = $sanitizer->sanitize($input);
⚠️ 关键注意事项
- 永远不要信任客户端输入:前端净化仅为防误、提升响应速度;后端必须重新清洗。
- 属性比标签更危险:onerror、href="javascript:"、style="background:url(javascript:...)" 均可触发 XSS,务必限制 ALLOWED_ATTR。
- 考虑上下文:若输出到
- 定期更新依赖:DOMPurify 等库持续修复新发现的 bypass 漏洞。
总结:用正则处理 HTML 是技术债务与安全黑洞的开端。选择成熟、社区验证的清洗库,并坚持“前后端双重净化”原则,才是构建健壮富文本处理能力的唯一可靠路径。











