Table of contents
Open Table of contents
JSX 转换后的 React 元素对象示例
{
type: 'marquee',
props: {
bgcolor: '#ffa7c4',
children: 'hi',
},
key: null,
ref: null,
$$typeof: Symbol.for('react.element'),
}
$$typeof 属性的作用及为何使用 Symbol 类型
作用说明:
- React 默认会对字符串内容进行转义,防止最基础的 XSS 攻击(如 script 标签或恶意 HTML 注入)。
- 但如果服务端存在安全漏洞,将用户传入的 JSON 直接作为 React 元素对象返回,攻击者就有机会构造恶意 React 元素(例如带有危险的
dangerouslySetInnerHTML属性)。这类攻击无法单纯依赖转义防护。 - 为此,React 从 v0.14 开始,为每个 React 元素对象添加了
$$typeof属性,并将其设置为Symbol.for('react.element')。由于 Symbol 是 JS 的基础类型之一,它无法通过 JSON 序列化/反序列化还原(普通字符串或数字可以被 JSON 还原),所以 React 可以通过检查$$typeof是否为特定的 Symbol 来识别和拒绝伪造元素,大大降低了此类 XSS 风险。 - 这一机制还能保证在多窗口、iframe 或多份 React 实例共存时,元素标志的一致性,因为
Symbol.for生成的全局 Symbol 在任何 JS 环境中都可一致识别。
兼容性说明:
- 在不支持 Symbol 的旧版本浏览器中,React 会退化使用
0xeac7这个常量作为标记,即形如:$$typeof: 0xeac7 - 这样做依然保持一定的校验能力,虽然安全性略低于 Symbol 方案,但已足以在大部分场景下区分合法的 React 元素对象。
总结
给 React 元素对象加上 $$typeof(采用 Symbol),本质是为了提高防伪能力、减少高阶 XSS 攻击面,是一项典型的安全设计。只做字符串转义只能覆盖简单攻击,只有严密的对象校验才能更好地保障前后端协作中的安全性。