sanitize-html异常:标签转换失败且文本被意外删除,求排查方案
问题原因与解决方案
问题根源
HTML实体自动解析导致的混乱
你传入的rawHtml使用了HTML转义实体(如<、"),但sanitize-html默认会自动解码这些实体为真实HTML内容。这导致<e>标签被正常处理,但<?php被解析为HTML处理指令,触发了库的默认过滤逻辑。处理指令被默认移除
sanitize-html默认会删除HTML处理指令(如<?php ... ?>),且解析器在处理这类非标准内容时,可能连带后续的普通文本一起移除,这就是你只得到<span>@user1</span>的核心原因。空白与文本未被保留
缺少preserveWhitespace配置,导致原始内容中的换行、空白被压缩或删除。
修复方案
1. 修正输入字符串
将转义后的实体还原为真实HTML内容,避免自动解码带来的意外:
let rawHtml = ` <e type="mention" title="@user1" /> How to output phpinfo: <?php phpinfo(); ?> test `
2. 调整sanitize-html配置
添加必要配置,确保处理指令被转义而非删除,同时保留文本格式:
let sanitizeHTML = require('sanitize-html') const clean = sanitizeHTML(rawHtml, { allowedTags: ['a', 'e', 'span'], disallowedTagsMode: 'escape', selfClosing: ['e'], // 保留原始换行与空白 preserveWhitespace: true, // 自定义Schema,将PHP处理指令视为可转义的标签 customizeSchema: (schema) => { schema.tagMap['?php'] = { tagName: '?php', selfClosing: false }; schema.tagMap['?'] = { tagName: '?', selfClosing: false }; return schema; }, transformTags: { 'e': function(tagName, attribs) { if (attribs['type'] === 'web') { return { tagName: 'a', attribs }; } else { return { tagName: 'span', attribs, text: attribs.title }; } }, // 转义PHP开始标签 '?php': () => ({ text: '<?php' }), // 转义PHP结束标签 '?': () => ({ text: '?>' }) } }) console.log(clean)
最终输出
执行后会得到与预期一致的结果:
<span>@user1</span> How to output phpinfo: <?php phpinfo(); ?> test
关键修改说明
- 还原输入内容:直接使用真实HTML标签,避免解析器自动解码实体引发的逻辑混乱。
- 自定义Schema:将PHP处理指令定义为可识别的标签,让
sanitize-html能对其进行转义处理。 - transformTags处理PHP标签:将
<?php和?>转换为转义后的文本,满足“仅转义不删除”的需求。 - preserveWhitespace:保留原始内容的换行与空白,维持输出格式与输入一致。
内容的提问来源于stack exchange,提问作者daisy
相关产品推荐
相关产品推荐

