为什么 React Elements 会有 $$typeof 这个属性?

发布时间:2019-08-05 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了为什么 React Elements 会有 $$typeof 这个属性?脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_406_0@
简评:debug 的时候看到 element 对象中有 $$tyPEof 这属性,于是查了一下这到底干嘛的。

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

<marquee @H_304_19@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,
  @H_360_78@ref: null,
  $$typeof: Symbol.for('react.element'), // ???? Who dis
}

这个 $$typeof 是什么?&nbsp;

各种前端框架出现之前,应用通常会构造 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 返回 <img> 也会当成字符串处理。要在 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?

脚本宝典总结

以上是脚本宝典为你收集整理的为什么 React Elements 会有 $$typeof 这个属性?全部内容,希望文章能够帮你解决为什么 React Elements 会有 $$typeof 这个属性?所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。