当前位置: 首页 > news >正文

停止使用 innerHTML:3 种安全渲染 HTML 的替代方案

innerHTML真的是前端世界里最“顺手也最危险”的按钮之一。 它方便到让人上瘾——也脆弱到让攻击者一旦把恶意内容塞进你的数据里,你的页面就会“热情执行”。

比如这种经典投毒:

<img src=x onerror=alert(1)>

只要你把它丢进innerHTML,浏览器就会毫不犹豫地配合演出。

下面这 3 种替代方案,才是更接近现代“正确姿势”的做法:有标准方向、有工业级方案、也有最安全的“根治法”。

1)未来标准派:Sanitizer API 的setHTML()

如果你确实需要渲染HTML 字符串,又不想自己写一堆过滤规则,那么Element.setHTML()是一个非常直球的方向:它会把 HTML 解析后进行清理,移除被认为不安全的元素/属性,再插入 DOM。

用法像这样:

const dirtyInput = '<img src=x onerror=alert(1)> <b>Hello</b>'; const el = document.getElementById('target'); // 会自动清掉 onerror 这类危险属性 el.setHTML(dirtyInput);

你要注意两点现实问题:

  • 它目前仍是实验性特性,MDN 也明确提示要看兼容性表,别盲目上生产。

  • 这套 API 目前出自 WICG 的孵化规范,并非已进入 W3C 标准轨道的“最终标准”。

一句话:方向很对,但上生产前先确认你的目标浏览器。

2)行业标准:DOMPurify

因为setHTML()还没做到“全平台稳用”,现实世界里更常见的安全做法是:先净化,再插入

而 DOMPurify 基本就是这条路上的“事实标准”:它专门用来清洗不可信 HTML,去掉潜在 XSS 内容(脚本、危险属性、奇怪的 SVG/MathML 边界等)。

用法也很简单:

import DOMPurify from 'dompurify'; const dirty = '<script>alert("hack")</script><div>Safe Content</div>'; const clean = DOMPurify.sanitize(dirty); element.innerHTML = clean;

注意:这里你还是用了innerHTML,但关键差别是——你插入的已经是“被清洗过的字符串”

安全侧的共识也很明确:当你需要做 HTML Sanitization 时,要用成熟方案、遵循安全指导(OWASP 的 XSS 预防原则里也强调了输出编码与必要时的净化)。

一句话:要渲染富文本,现在就用 DOMPurify,别自研“简易过滤器”。

3)最安全的方法: document.createElement()

如果你并不需要把“HTML 字符串”当 HTML 渲染出来,那最安全的路线其实是:别让浏览器把输入当成可执行结构

直接用 DOM API 构建节点,用textContent填内容——浏览器会把它当文本,不会当脚本,也就天然避免 XSS。

const div = document.createElement('div'); div.textContent = userInput; // 默认安全:只会当文字 div.classList.add('my-class'); document.body.appendChild(div);

这招的气质就是:你不需要“清洗”,因为你根本不给它“执行的机会”。

最后

  • 纯文本:优先textContent(又快又安全)

  • 必须渲染富文本(今天就要上线):用 DOMPurify

  • 想跟上未来标准:关注/试用setHTML(),但先过兼容性这关

全栈AI·探索:涵盖动效、React Hooks、Vue 技巧、LLM 应用、Python 脚本等专栏,案例驱动实战学习,点击二维码了解更多详情。

最后:

CSS终极指南

Vue 设计模式实战指南

20个前端开发者必备的响应式布局

深入React:从基础到最佳实践完整攻略

python 技巧精讲

React Hook 深入浅出

CSS技巧与案例详解

vue2与vue3技巧合集

http://www.jsqmd.com/news/270695/

相关文章:

  • FSMN VAD部署教程:Linux环境从零配置指南
  • 开源语音技术突破:FSMN-VAD模型结构深度解析
  • CV-UNet应用案例:网店商品图批量标准化处理
  • SGLang性能实战对比:RadixAttention如何提升KV缓存命中率?
  • Speech Seaco Paraformer是否支持Ogg?小众格式兼容性测试报告
  • SenseVoice Small语音识别实战|附情感与声学事件标签提取技巧
  • NotaGen部署优化:多GPU并行生成配置指南
  • RexUniNLU性能优化:让中文NLP任务提速50%
  • 图像修复工具横向评测:GPEN在中文社区的适用性分析
  • 开源大模型落地新选择:Qwen3系列多场景应用实战指南
  • 5个SAM3创意玩法:云端GPU开箱即用,10元全体验
  • GPEN错误日志查看:排查问题的关键信息定位方法
  • Emotion2Vec+ Large成本效益分析:自建vs云服务ROI对比报告
  • IndexTTS 2.0+HTML:前端轻松嵌入AI语音播放器
  • DCT-Net实战案例:企业形象设计卡通化解决方案
  • 智能体是自主与它主的协同调度
  • AI初创公司首选:Qwen2.5-7B低成本商用部署完整指南
  • AI图像风格迁移新选择|DCT-Net GPU镜像实现高质量二次元虚拟形象生成
  • Elasticsearch内存模型配置:Kubernetes环境手把手教程
  • 二叉搜索树,平衡二叉树,红黑树总结
  • Unreal Fur 假毛发 草地 Grass
  • Qwen-Image-Layered升级日志:新版本带来了哪些改进?
  • 马斯克全球最大GPU集群建成,Grok要起飞了!
  • 智能填空系统实战:BERT模型部署指南
  • 机器人学习!(二)ROS2-环境配置(6)2026/01/19
  • 小白也能玩转文本排序!Qwen3-Reranker-0.6B保姆级教程
  • SGLang-v0.5.6部署实战:混合精度推理加速技巧
  • GTE中文语义相似度计算实战:新闻标题去重系统构建
  • 快速理解LED显示屏与NovaStar控制系统的安装流程
  • SenseVoice Small保姆级教程:语音识别模型训练