dangerouslySetInnerHTML 是 React 为浏览器 DOM 提供 innerHTML 的替换方案,用来在 JSX 中渲染 HTML 格式的字符串内容
通常来讲,使用代码直接设置 HTML 存在风险,因为很容易无意中使用户暴露于跨站脚本(XSS)的攻击
HTML 5 中规定:不执行由 innerHTML 插入的 <script> 标签。
但是,有很多不依赖 script 标签去执行 JavaScript 的方式。比如,以下代码会执行 alert 弹窗,造成安全问题:
// 注意:此处图片的 onerror 属性的代码,还是会被执行,不仅影响了用户体验,还会存在 XSS 攻击问题
<div
className="content-html dg-html"
dangerouslySetInnerHTML={{
__html: "<img src='x' onerror='alert(1)'>",
}}
></div>
因此,为了安全可以通过类似于 dompurify 包,来对 HTML 字符串内容进行“消毒”:
import DOMPurify from 'dompurify';
// 比如,将 '<div><script>alert(111)</script></div>' 转化为: '<div></div>'
// 比如,将 '<img src="x" onerror="alert(1)">' 转化为:'<img src="x" />'
const clean = DOMPurify.sanitize(dirty);
步骤:
- 安装 dompurify 和 类型声明文件:
yarn add dompurifyyarn add -D @types/dompurify - 导入 dompurify 包
- 通过 dangerouslySetInnerHTML 来展示消毒后的 HTML 内容
核心代码:
import DOMPurify from 'dompurify';
<div
className="content-html dg-html"
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(content),
}}
/>;