React 中 $$typeof 的做用

image

圖片來源於互聯網前端

當在控制檯打印一個 React 組件的時候,能看出組件就是一個對象,也能夠說是虛擬 dom,這個對象上面包含了所須要渲染的 dom 節點的標籤名稱、屬性、子節點等信息。同時也有一個 $$typeof 的屬性。react

$$typeof 是如何添加在 React 對象上的

jsx 語法在被 babel 解析的時候調用 React.createElement 方法,那麼咱們看一下 createElement 方法的實現git

export function createElement(type, config, children) {

    ...

    return ReactElement(
        type,
        key,
        ref,
        self,
        source,
        ReactCurrentOwner.current,
        props,
    )
}
複製代碼

createElement 方法返回了 ReactElement 方法的執行結果,那麼看一下 ReactElement 方法的實現github

const ReactElement = function(type, key, ref, self, source, owner, props) {
  const element = {
    $$typeof: REACT_ELEMENT_TYPE,
    type: type,
    key: key,
    ref: ref,
    props: props,
    _owner: owner,
  }

  ...

  return element;
}
複製代碼

從上面的代碼中能夠看到 $$typeof 屬性就是在 ReactElement 方法中添加到 React 對象上的。其值爲變量 REACT_ELEMENT_TYPE。數據庫

變量 REACT_ELEMENT_TYPE 是如何定義的

ReactSymbols.js 文件中能夠看到變量 REACT_ELEMENT_TYPE 的定義瀏覽器

const hasSymbol = typeof Symbol === 'function' && Symbol.for;

export const REACT_ELEMENT_TYPE = hasSymbol
    ? Symbol.for('react.element')
    : 0xeac7;

    ...
複製代碼

若是當前瀏覽器支持 Symbol 則 REACT_ELEMENT_TYPE 爲 Symbol 類型的變量,不然爲 16 進制的數字。安全

添加 $$typeof 的意義

爲了安全babel

假如前端指望從接口中獲取一個字符串渲染在頁面中cookie

...

render() {
  <div>{serverData.text}</div>
}
複製代碼

然而因爲服務端在數據入庫時存在漏洞,有用戶惡意存入了這樣的數據併發

const text = {
  key: null
  type: 'script',
  props: {src: 'http://...'},
}
複製代碼

若是這條數據被成功渲染,那麼就是一個存在風險的第三方 script 標籤入侵到了當前用戶的頁面,它能作什麼徹底取決於它想作什麼,好比獲取併發送用戶的 cookie、localStorage,比較可愛的狀況是給用戶的頁面上彈十萬個彈窗。

爲了防止這種狀況的發生,React 0.14 版本加入了 $$typeof

數據庫是沒法存儲 Symbol 類型數據的,因此用戶惡意存入的數據是沒法帶有合法的 $$typeof 字段的。

當 React 在渲染的時候加上對 $$typeof 合法性的驗證便可防止惡意代碼的插入。低版本不支持 Symbol 的瀏覽器是沒有這個安全特性的。

相關文章
相關標籤/搜索