Skip to content
Mithril.js 2
Main Navigation 指南API

繁體中文

English
简体中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

繁體中文

English
简体中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

外觀

Sidebar Navigation

API

核心 API

m(selector, attributes, children)

render(element, vnodes)

mount(root, component)

route(root, defaultRoute, routes)

request(options)

parseQueryString(string)

buildQueryString(object)

buildPathname(object)

parsePathname(string)

trust(html)

fragment(attrs, children)

redraw()

censor(object, extra)

可選 API

stream()

指南

本頁導覽

trust(html) ​

描述 ​

將 HTML 或 SVG 字串轉換為不經過轉義的 HTML 或 SVG。請勿在未經過濾的使用者輸入上使用 m.trust。

在考慮使用 m.trust 之前,請務必先嘗試使用替代方法。

簽名式 ​

vnode = m.trust(html)

參數類型是否必填描述
htmlString是包含 HTML 或 SVG 文字的字串
回傳值Vnode代表輸入字串的受信任 HTML vnode

如何閱讀簽名

運作原理 ​

預設情況下,Mithril.js 會轉義所有值,以防止一類稱為 XSS 注入 的安全問題。

javascript
var userContent = "<script>alert('evil')</script>";
var view = m('div', userContent);

m.render(document.body, view);

// equivalent HTML
// <div>&lt;script&gt;alert('evil')&lt;/script&gt;</div>

但是,有時需要呈現富文本和格式標記。為了滿足這種需求,m.trust 會建立受信任的 HTML vnode,這些 vnode 會呈現為 HTML。

javascript
var view = m('div', [m.trust("<h1>Here's some <em>HTML</em></h1>")]);

m.render(document.body, view);

// equivalent HTML
// <div><h1>Here's some <em>HTML</em></h1></div>

受信任的 HTML vnode 是物件,而不是字串;因此,它們不能與常規字串串聯。

安全性考量 ​

您必須過濾 m.trust 的輸入內容,以確保 HTML 字串中沒有使用者產生的惡意程式碼。如果您不過濾 HTML 字串,並將其標記為受信任,則 HTML 字串中的任何非同步 JavaScript 呼叫都可能被觸發,並以檢視頁面使用者的權限執行。

HTML 字串可能包含可執行程式碼的方式有很多種。注入安全攻擊最常見的方式是在 <img> 或 <iframe> 標籤中新增 onload 或 onerror 屬性,或是使用不平衡的引號 (例如 " onerror="alert(1)) 在未過濾的字串插值中注入可執行上下文。

javascript
var data = {};

// 易受攻擊的 HTML 字串範例
var description =
  "<img alt='" + data.title + "'> <span>" + data.description + '</span>';

// 利用 JavaScript 相關屬性進行攻擊
data.description = "<img onload='alert(1)'>";

// 使用不平衡的標籤進行攻擊
data.description = "</span><img onload='alert(1)'><span";

// 使用不平衡的引號進行攻擊
data.title = "' onerror='alert(1)";

// 使用不同的屬性進行攻擊
data.title = "' onmouseover='alert(1)";

// 不使用 JavaScript 的攻擊
data.description =
  "<a href='https://evil.com/login-page-that-steals-passwords.html'>Click here to read more</a>";

建立惡意程式碼有無數種不明顯的方法,因此強烈建議您使用允許的 HTML 標籤、屬性和屬性值的白名單,而不是黑名單來過濾使用者輸入。還強烈建議您使用適當的 HTML 解析器,而不是使用正則表達式進行過濾,因為正則表達式極難測試所有邊緣情況。

不執行的腳本 ​

即使有很多隱晦的方式可以使 HTML 字串執行 JavaScript,<script> 標籤在 HTML 字串中出現時,通常不會執行。

基於歷史因素,瀏覽器會忽略透過 innerHTML 插入到 DOM 的 <script> 標籤。它們這樣做是因為一旦元素準備就緒(因此具有可訪問的 innerHTML 屬性),如果腳本呼叫類似 document.write("</body>") 的內容,則渲染引擎無法回溯到解析階段。

對於來自 jQuery 的開發人員來說,這種瀏覽器行為可能看起來令人驚訝,因為 jQuery 實現了專門用於查找腳本標籤並在此場景中執行它們的程式碼。Mithril.js 遵循瀏覽器行為。如果需要 jQuery 行為,您應該考慮將程式碼移出 HTML 字串並移入 oncreate 生命週期函式,或使用 jQuery(或重新實現其腳本解析程式碼)。

避免信任 HTML ​

一般來說,除非您明確地呈現富文本並且沒有其他方法可以獲得您想要的結果,否則您應該避免使用 m.trust。

javascript
// 避免
m('div', m.trust('hello world'));

// 優先
m('div', 'hello world');

避免盲目複製和貼上 ​

常見的 m.trust 濫用方式是使用第三方服務,其教程包含要複製和貼上的 HTML 程式碼。在大多數情況下,應使用 vnode(通常透過 m() 實用程式)編寫 HTML。

以下是 Facebook 讚按鈕 的範例程式碼片段:

html
<!-- 載入 Facebook JavaScript SDK -->
<div id="fb-root"></div>
<script>
  (function (d, s, id) {
    var js,
      fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s);
    js.id = id;
    js.src = '//connect.facebook.net/en_US/sdk.js#xfbml=1';
    fjs.parentNode.insertBefore(js, fjs);
  })(document, 'script', 'facebook-jssdk');
</script>

<!-- 您的讚按鈕程式碼 -->
<div
  class="fb-like"
  data-href="https://www.your-domain.com/your-page.html"
  data-layout="standard"
  data-action="like"
  data-show-faces="true"
></div>

以下是如何將其重構為 Mithril.js 元件,以避免 m.trust:

javascript
var FacebookLikeButton = {
  oncreate: function () {
    (function (d, s, id) {
      var js,
        fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) return;
      js = d.createElement(s);
      js.id = id;
      js.src = '//connect.facebook.net/en_US/sdk.js#xfbml=1';
      fjs.parentNode.insertBefore(js, fjs);
    })(document, 'script', 'facebook-jssdk');
  },
  view: function () {
    return [
      m('#fb-root'),
      m(
        '.fb-like[data-href=https://www.your-domain.com/your-page.html][data-layout=standard][data-action=like][data-show-faces=true]'
      ),
    ];
  },
};

上面的 Mithril.js 元件只是將腳本標籤的程式碼複製到 oncreate 鉤子中,並使用 Mithril.js 的 m() 語法宣告剩餘的 HTML 標籤。

避免 HTML 實體 ​

常見的 m.trust 濫用方式是將其用於 HTML 實體。更好的方法是使用相應的 unicode 字元:

javascript
// 避免
m('h1', 'Coca-Cola', m.trust('&trade;'));

// 優先
m('h1', 'Coca-Cola™');

可透過適用語言的鍵盤配置輸入帶重音符號的字元的 Unicode 字元。此外,還可以選擇記住鍵盤快捷鍵以產生常用符號 (例如,Windows 中的 Alt+0153 或 Mac 上的 Option+2 用於 ™ 符號)。另一種簡單的產生方式是簡單地從 unicode 字元表 複製並貼上所需的字元。另一種相關方法是輸入逸出的 Unicode 碼位 (例如,™ 符號的 "\u2122")。

所有能以 HTML 實體表示的字元都有 Unicode 對應項,包括不可見字元,例如 &nbsp; 和 &shy; 等。

為了避免編碼問題,您應該將 JavaScript 檔案的檔案編碼設定為 UTF-8,並在主機 HTML 檔案中新增 <meta charset="utf-8"> meta 標籤。

Pager
上一頁parsePathname(string)
下一頁fragment(attrs, children)

以 MIT 授權條款 發布。

版權所有 (c) 2024 Mithril Contributors

https://mithril.js.org/trust.html

以 MIT 授權條款 發布。

版權所有 (c) 2024 Mithril Contributors