简评:debug 的时候看到 element 对象中有 $$typeof 这属性,于是查了一下这到底干嘛的。

我们知道,通过 JSX 创建一个 React Elements 时:

<marquee bgcolor="#ffa7c4">hi</marquee>

实际上调用的是 React.createElement 方法:

React.createElement(/* type */ 'marquee',/* props */ { bgcolor: '#ffa7c4' },/* children */ 'hi'
)

该方法会返回一个 React Element 对象,大概长这样:

{type: 'marquee',props: {bgcolor: '#ffa7c4',children: 'hi',},key: null,ref: null,$$typeof: Symbol.for('react.element'), // ? Who dis
}

这个 $$typeof 是什么?

各种前端框架出现之前,应用通常会构造 HTML 并将它们插入到 DOM 中,例如:

const messageEl = document.getElementById('message');
messageEl.innerHTML = '<p>' + message.text + '</p>';

这代码一般能正常工作,除非你的 message.text 返回 '<img src onerror="stealYourPassword()">' 这样的字符串。

为了防止这种情况,可以使用类似于 document.createTextNode()textContent 仅处理 text 的 api。也可以通过预处理替换 < > 这类特殊的字符。但是这样还是有很多潜在的问题。所以现代前端框架像 React 会为字符串转义成文字内容:

<p>{message.text}
</p>

就算 message.text 返回 也会当成字符串处理。要在 React 元素中呈现 HTML ,则需要编写dangerouslySetInnerHTML={{ __html: message.text }},这有助于你在审查代码的时候重视它。

但是这样仍然无法完全禁止注入攻击,例如:<a href={user.website}>,注意 website 为 'javascript: stealYourPassword()'的情况。 对用户输入使用 ... 运算符也很危险 <div {...userData}>

为什么需要 $$typeof

通过上面的介绍你可能已经猜到了,$$typeof 是为了防止 XSS 攻击。

前面介绍了,React 元素大概是这样的(没有包含 $$typeof 这个属性的情况):

{type: 'marquee',props: {bgcolor: '#ffa7c4',children: 'hi',},key: null,ref: null
}

试想这样一种情况,服务器允许用户储存任意的 JSON 数据。那么就可以手动构建 React Element 对象传入到元素中。例如:

// Server could have a hole that lets user store JSON
let expectedTextButGotJSON = {type: 'div',props: {dangerouslySetInnerHTML: {__html: '/* put your exploit here */'},},// ...
};
let message = { text: expectedTextButGotJSON };// Dangerous in React 0.13
<p>{message.text}
</p>

所以 React 0.14 使用 Symbol 标记每个 React 元素。

{type: 'marquee',props: {bgcolor: '#ffa7c4',children: 'hi',},key: null,ref: null,$$typeof: Symbol.for('react.element'),
}

这样就可以规避这个问题,使用 Symbol 类型是因为 JSON 中无法传递 Symbol。React 会检查 element.$$typeof 然后拒绝处理非法的元素。

原文: Why Do React Elements Have a $$typeof Property?

转载于:https://www.cnblogs.com/jpush88/p/10206944.html

最新文章

  1. asp.net code-behind
  2. 国自然放榜又没中,您以为缺的是文章,其实是这个
  3. Spring MVC 中使用 Google kaptcha 验证码
  4. python class 是否存在某个变量_一文抵十课,考验你的Python变量是否理解透彻了
  5. 解决redis启动时的警告
  6. try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后?...
  7. QUIC - 低时延互联网传输层协议
  8. MemCache在tomcat中的负载均衡和session交叉存放
  9. 计算机网络中使用的双绞线通常是16芯的,自考计算机应用基础判断题试题答案...
  10. C++第五章课后习题16-字符串按逆序输出
  11. 《我们不一样团队》项目需求分析改进
  12. 阿里,百度,腾讯等一线互联网公司中,Java开发的招聘标准
  13. 计算机在信息社会中最广泛的应用是,计算机一级考题及答案整理
  14. 种子文件转成为磁力链接 下载BT磁力转换小工具
  15. MinGw编译opencv教程
  16. 计算机一级office题库百度云,历年全国计算机等级考试一级MSOffice真题
  17. 微信中怎么打开apk文件 微信跳转打开外部浏览器打开apk文件
  18. 2021暑假Leetcode刷题——Two Pointers(1)
  19. 基于FPGA的2FSK调制解调器
  20. Unity内置管线升级URP之色彩空间(伽马、sRGB、Gamma Space和Linear Space)

热门文章

  1. Windows UWP开发系列 – 3D变换
  2. onpaste事件不生效_从实际开发中来看JavaScript事件循环的使用场景
  3. centos amd双显卡_讯景RX590 AMD 50周年纪念版显卡评测
  4. 在计算机技术中描述信息最小单位是,计算机二级考试单选题
  5. 3310复刻版 java_终于等到你:诺基亚3310复刻版开箱简评
  6. pythonwhile列表_Python编程:while循环处理列表和字典
  7. 宽依赖和窄依赖_Spark术语解释及宽窄依赖执行原理,代码分析
  8. 成田机场坐access到品川_关西机场交通攻略
  9. vue router html,vue-router.html
  10. C#获取当前进程、项目路径的方法