html.escape()必须设quote=true,因默认仅转义、&,漏掉单双引号,无法防御value='...'等单引号属性截断型xss;quote=true补全"和'转义,覆盖双/单引号属性场景。

为什么html.escape()在Python里必须加quote=True
不加这个参数,'(单引号)不会被转义,而它在value='...'这类单引号属性中会直接截断属性值——攻击者输入test' onfocus=alert(1) autofocus='就能触发XSS。默认quote=False只转义、<code>>、&,漏掉两个关键边界字符。quote=True才补上"和'(或'),覆盖双/单引号属性场景。
前端用textContent比正则替换&<code>>更可靠
手动写正则如/[&'"]/g容易漏掉嵌套情况:比如<本意是显示“&成&,再转成<code>,结果变成<code><,浏览器解码两次后仍显示——这不是预期的文本,而是潜在的标签起点。而<code>textContent走的是浏览器原生解析器路径,完全复现HTML词法分析逻辑,不会多转也不会少转。它不依赖字符串顺序,也不怕实体嵌套。
innerHTML = escapeHtml(str)和textContent = str不能混用
常见错误是:后端已用html.escape()处理过数据,前端拿到JSON后还用模板字符串拼进innerHTML,例如:el.innerHTML = `<div>${data.content}</div>`。这时服务端那层转义被JS插值“吃掉”了——${data.content}是纯字符串插入,不是HTML解析上下文,浏览器会把当字面量渲染,而不是<code>。真正安全的组合只有两种:
- 纯文本展示:一律用
el.textContent = data.content - 必须插HTML:确认字段是可信富文本,且经
DOMPurify.sanitize()清洗过,再赋给innerHTML
数字实体比命名实体<code>兼容性更强
IE8及更早版本不支持',必须写';中文、emoji等Unicode字符没有命名实体(比如❤️是U+2764 + U+FE0F两个码点),只能靠❤️这种数字形式。服务端若用html.escape(..., quote=True),Python 3.4+默认输出命名实体,但遇到非ASCII字符会自动回落为十进制数字实体——这点不用干预,但要注意别自己手写去替换,否则可能在老旧环境失效。
innerHTML、input.value、style.cssText、location.href里需要的编码方式完全不同。没切对上下文,转得再全也白搭。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











