圖片來源於互聯網前端
當在控制檯打印一個 React 組件的時候,能看出組件就是一個對象,也能夠說是虛擬 dom,這個對象上面包含了所須要渲染的 dom 節點的標籤名稱、屬性、子節點等信息。同時也有一個 $$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。數據庫
在 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 進制的數字。安全
爲了安全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 的瀏覽器是沒有這個安全特性的。