处理如何用 innerHTML 渲染动态列表并防范 XSS 脚本攻击漏洞这类问题时,先确认目标场景,再按步骤核对配置或玩法细节。
应优先使用 textContent 或 createElement + append 渲染用户输入,避免 innerHTML 引发 XSS;必须渲染 HTML 时须用 DOMPurify 等库净化;服务端需配合上下文编码与 CSP 头防护。
直接用 innerHTML 渲染用户输入的内容极易引发 XSS 攻击,必须先做内容净化或改用更安全的替代方案。
如果只是展示纯文本内容(比如列表项的文字),完全避免 HTML 解析是最稳妥的做法:
textContent 设置文字内容,浏览器会自动转义所有 HTML 特殊字符(< → )
document.createElement 创建节点,再用 textContent 设置子文本,最后 append 到父容器<ul id="list"></ul>
const names = ['Alice', '<script>alert(1)</script>', 'Bob'];const ul = document.getElementById('list');names.forEach(name => { const li = document.createElement('li'); li.textContent = name; // 自动转义,脚本不会执行 ul.append(li);});
仅当业务强依赖富文本(如后台管理员发布的公告),且内容来源绝对可控时,才考虑净化后使用 innerHTML。切勿对用户直填内容这么做:
onclick、onerror 等)、<script>、<iframe>、javascript: 协议等危险标签和行为const dirty = '<div onclick="alert(1)">Hello</div><script>fetch("/xss")</script>';const clean = DOMPurify.sanitize(dirty); // → '<div>Hello</div>'list.innerHTML = clean;
前端净化只是最后一道防线。XSS 防御必须前后端协同:
<、>、& 转义)bleach、Node.js 的 sanitize-html)处理后再下发Content-Security-Policy: default-src 'self' 可大幅降低 XSS 成功概率,尤其阻止内联脚本和未授权外链以下写法看似方便,实则高危:
el.innerHTML = '<li>' + userInput + '</li>' —— 拼接即漏洞el.innerHTML = marked(userInput) —— Markdown 渲染器若未配置 HTML 禁用,会保留原始标签el.innerHTML = template.replace('{{name}}', data.name) —— 模板字符串拼接同样不安全textContent 或经净化后插入,绝不拼接 HTML 字符串