<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                你覺得你在寫 JSX: ~~~jsx <marquee bgcolor="#ffa7c4">hi</marquee> ~~~ 其實,你在調用一個方法: ~~~jsx React.createElement( /* type */ 'marquee', /* props */ { bgcolor: '#ffa7c4' }, /* children */ 'hi' ) ~~~ 之后方法會返回一個對象給你,我們稱此對象為React的*元素*(element),它告訴 React 下一個要渲染什么。你的組件(component)返回一個它們組成的樹(tree)。 ~~~jsx { type: 'marquee', props: { bgcolor: '#ffa7c4', children: 'hi', }, key: null, ref: null, $$typeof: Symbol.for('react.element'), // ??是誰} ~~~ 如果你用過 React,對`type`、`props`、`key`、 和`ref`應該熟悉。**但`$$typeof`是什么?為什么用`Symbol()`作為它的值**? 這又是一個與你學習使用 React 不*相關*的點,但了解后你會覺得舒坦。這篇文章里也提到了些關于安全的提示,你可能會感興趣。也許有一天你會有自己的UI庫,這些都會派上用場的,我真的希望如此。 * * * 在客戶端 UI 庫變得普遍且具有基本保護作用之前,應用程序代碼通常是先構建 HTML,然后把它插入 DOM 中: ~~~jsx const messageEl = document.getElementById('message'); messageEl.innerHTML = '<p>' + message.text + '</p>'; ~~~ 這樣看起來沒什么問題,但當你`message.text`的值類似`'<img src onerror="stealYourPassword()">'`時,**你不會希望別人寫的內容在你應用的 HTML 中逐字顯示的。** (有趣的是:如果你只是在前端渲染,這里為`<script>`標簽,JavaScript 代碼不會被運行。但[不要因此](https://gomakethings.com/preventing-cross-site-scripting-attacks-when-using-innerhtml-in-vanilla-javascript/)讓你陷入已經安全的錯覺。) 為什么防止此類攻擊,你可以用只處理文本的`document.createTextNode()`或者`textContent`等安全的 API。你也可以事先將用戶輸入的內容,用轉義符把潛在危險字符(`<`、`>`等)替換掉。 盡管如此,這個問題的成本代價很高,且很難做到用戶每次輸入都記得轉換一次。**因此像React等新庫會默認進行文本轉義:** ~~~jsx <p> {message.text} </p> ~~~ 如果`message.text`是一個帶有`<img>`或其他標簽的惡意字符串,它不會被當成真的`<img>`標簽處理,React 會先進行轉義*然后*插入 DOM 里。所以`<img>`標簽會以文本的形式展現出來。 要在 React 元素中渲染任意 HTML,你不得不寫`dangerouslySetInnerHTML={{ __html: message.text }}`。**其實這種愚蠢的寫法是一個功能**,在 code reviews 和代碼庫審核時,你可以非常清晰的定位到代碼。 * * * **這意味著React完全不懼注入攻擊了嗎?不**,HTML 和 DOM 暴露了[大量攻擊點](https://github.com/facebook/react/issues/3473#issuecomment-90594748),對 React 或者其他 UI 庫來說,要減輕傷害太難或進展緩慢。大部分存在的攻擊方向涉及到屬性,例如,如果你渲染`<a href={user.website}`,要提防用戶的網址是`'javascript: stealYourPassword()'`。 像`<div {...userData}>`寫法幾乎不受用戶輸入影響,但也有危險。 React[可以](https://github.com/facebook/react/issues/10506)逐步提供更多保護,但在很多情況下,威脅是服務器產生的,這不管怎樣都[應該](https://github.com/facebook/react/issues/3473#issuecomment-91327040)要避免。 不過,轉義文本這第一道防線可以攔下許多潛在攻擊,知道這樣的代碼是安全的就夠了嗎? ~~~jsx // 自動轉義 <p> {message.text} </p> ~~~ **好吧,也不總是有效的**。這就是`$$typeof`的用武之地了。 * * * React 元素(elements)是設計好的*plain object*: ~~~jsx { type: 'marquee', props: { bgcolor: '#ffa7c4', children: 'hi', }, key: null, ref: null, $$typeof: Symbol.for('react.element'), } ~~~ 雖然通常用`React.createElement()`創建它,但這不是必須的。有一些 React 用例來證實像上面這樣的*plain object*元素是有效的。當然,你不會*想*這樣寫的,但這[可以用來](https://github.com/facebook/react/pull/3583#issuecomment-90296667)優化編譯器,在 workers 之間傳遞 UI 元素,或者將 JSX 從 React 包解耦出來。 但是,如果你的服務器有允許用戶存儲任意 JSON 對象的漏洞,而前端需要一個字符串,這可能會發生一個問題: ~~~jsx // 服務端允許用戶存儲 JSON let expectedTextButGotJSON = { type: 'div', props: { dangerouslySetInnerHTML: { __html: '/* 把你想的擱著 */' }, }, // ...}; let message = { text: expectedTextButGotJSON }; // React 0.13 中有風險 <p> {message.text}</p> ~~~ 在這個例子中,React 0.13[很容易](http://danlec.com/blog/xss-via-a-spoofed-react-element)受到 XSS 攻擊。再次聲明,**這個攻擊是服務端存在漏洞導致的**。不過,React 會為了大家的安全做更多工作。從 React 0.14 開始,它做到了。 React 0.14 修復手段是用 Symbol 標記每個 React 元素(element): ~~~jsx { type: 'marquee', props: { bgcolor: '#ffa7c4', children: 'hi', }, key: null, ref: null, $$typeof: Symbol.for('react.element'),} ~~~ 這是個有效的辦法,因為JSON不支持`Symbol`類型。**所以即使服務器存在用JSON作為文本返回安全漏洞,JSON 里也不包含`Symbol.for('react.element')`**。React 會檢測`element.$$typeof`,如果元素丟失或者無效,會拒絕處理該元素。 特意用`Symbol.for()`的好處是**Symbols 通用于 iframes 和 workers 等環境中**。因此無論在多奇怪的條件下,這方案也不會影響到應用不同部分傳遞可信的元素。同樣,即使頁面上有很多個 React 副本,它們也 「接受」 有效的`$$typeof`值。 ## 摘自 [ 為什么React元素有一個$$typeof屬性?](https://overreacted.io/zh-hans/why-do-react-elements-have-typeof-property/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看