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 = {};

// Sample vulnerable HTML string
var description =
  "<img alt='" + data.title + "'> <span>" + data.description + '</span>';

// An attack using JavaScript-related attributes
data.description = "<img onload='alert(1)'>";

// An attack using unbalanced tags
data.description = "</span><img onload='alert(1)'><span";

// An attack using unbalanced quotes
data.title = "' onerror='alert(1)";

// An attack using a different attribute
data.title = "' onmouseover='alert(1)";

// An attack that does not use JavaScript
data.description =
  "<a href='https://evil.com/login-page-that-steals-passwords.html'>Click here to read more</a>";

创建恶意代码的方法数不胜数,因此强烈建议您使用允许的 HTML 标签、属性和属性值的白名单,而不是黑名单来清理用户输入。还强烈建议您使用适当的 HTML 解析器,而不是使用正则表达式进行清理,因为正则表达式极难测试所有边界情况。

不会运行的脚本 ​

尽管有许多复杂的方法可以使 HTML 字符串运行 JavaScript,但 HTML 字符串中的 <script> 标签通常不会运行。

出于历史原因,浏览器会忽略通过 innerHTML 插入到 DOM 中的 <script> 标签。 这样做的原因是,一旦元素准备就绪(因此具有可访问的 innerHTML 属性),如果脚本调用类似 document.write("</body>") 的内容,则渲染引擎无法回溯到解析阶段。

对于来自 jQuery 的开发人员来说,这种浏览器行为可能会让人感到意外,因为 jQuery 专门实现了代码来查找脚本标签并在此场景中运行它们。Mithril.js 遵循浏览器行为。如果需要 jQuery 行为,您应该考虑将代码移出 HTML 字符串并移入 oncreate 生命周期方法,或者使用 jQuery(或重新实现其脚本解析代码)。

避免信任 HTML ​

作为一般规则,除非您需要明确渲染富文本且没有其他方法可用,否则应避免使用 m.trust。

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

// PREFER
m('div', 'hello world');

避免盲目复制和粘贴 ​

滥用 m.trust 的一种常见方式是在使用第三方服务时,这些服务的教程包含需要复制和粘贴的 HTML 代码。在大多数情况下,应使用 vnode 编写 HTML(通常通过 m() 实用程序)。

这是 Facebook Like 按钮 的示例代码段:

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>

这是如何以避免 m.trust 的方式将其重构为 Mithril.js 组件:

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
// AVOID
m('h1', 'Coca-Cola', m.trust('&trade;'));

// PREFER
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