安全地将HTML注入Polymer模板

时间:2014-09-30 05:53:36

标签: dart dart-polymer dart-html

在自定义元素中,我尝试用HTML替换项目的正文文本以换行符和链接。当我刚刚处理换行符(nl2br())时它正在工作,但在处理链接时却没有(linkify())。

  get formattedBody {
    if (item.isEmpty) return 'Loading...';
    return "${InputFormatter.nl2br(InputFormatter.linkify(item['body']))}";
  }

  itemChanged() {
    // Trick to respect line breaks.
    HtmlElement body = $['body'];
    body.innerHtml = formattedBody;
  }

我得到一个温暖而安全的安全信息,例如:

Removing disallowed attribute <A href="http://miamiherald.typepad.com/the-starting-gate/2014/09/news-.html">

我也试过setInnerHtml(),但没有用。

想法?谢谢!

2 个答案:

答案 0 :(得分:3)

您需要传递NodeValidator,配置为允许特定标记和属性。

此问题HTML Tags Within Internationalized Strings In Polymer.dart包含一个自定义元素的示例,该元素允许使用聚合表达式传递HTML。该实现演示了如何使用NodeValidator

您可以允许其他元素/属性集或自定义元素/属性,而不是..allowTextElements()。自动填充应显示可能的选项。

另见
- Dart, why does using innerHtml to set shadow root content work but appendHtml doesn't?
- Dart Removing disallowed attribute after editor upgraded
- Mustache Template usage in Dart
- in dart parse HTML string to DOM

我使用了

NodeValidator nodeValidator = new NodeValidatorBuilder()
    ..allowNavigation(new MiamiHeraldUrlPolicy());

aContainer.setInnerHtml('<a href="http://miamiherald.typepad.com/the-starting-gate/2014/09/news-.html">bla</a>', 
    validator: nodeValidator);
class MiamiHeraldUrlPolicy implements UriPolicy {
  MiamiHeraldUrlPolicy();

  RegExp regex = new RegExp(r'(?:http://|https://|//)?miamiherald.typepad.com/.*');

  bool allowsUri(String uri) {
    return regex.hasMatch(uri);
  }
}

答案 1 :(得分:2)

我有一个<safe-html>元素正在运行。在Chrome上验证,甚至在Safari上验证后dart2js。如果您希望我将它变成pub.dartlang.org上的lib,请投票给出这个答案。

用法:

<safe-html validator="{{nodeValidator}}">{{someHtml}}</safe-html>

(传入您自己的validator是可选的。没有它,我们将使用默认值。)

safe_html.html:

<link rel="import" href="../../../../../../../packages/polymer/polymer.html">
<polymer-element name="safe-html">
  <template>
    <div id="container"></div>
  </template>

  <script type="application/dart" src='safe_html.dart'></script>
</polymer-element>

safe_html.dart:

library safe_html;

import 'dart:async';
import "dart:html";

import "package:polymer/polymer.dart";

@CustomTag("safe-html")
class SafeHtml extends PolymerElement  {
  @published NodeValidator validator = new NodeValidatorBuilder()
    ..allowHtml5(uriPolicy: new DefaultUriPolicy());

  SafeHtml.created() : super.created();

  addFragment() {
    DivElement container = $['container'];
    String fragment =  this.text;
    container.setInnerHtml(fragment, // Set the fragment in a safe way.
      validator: validator);
    this.text = ""; // Clear the original fragment passed to the element.
  }

  attached() {
    addFragment();
  }
}

class DefaultUriPolicy implements UriPolicy {
  DefaultUriPolicy();

  // Allow all external, absolute URLs.
  RegExp regex = new RegExp(r'(?:http://|https://|//)?.*');

  bool allowsUri(String uri) {
    return regex.hasMatch(uri);
  }
}

如果您选择传递自己的NodeValidator,请通过在使用<safe-html>的父元素中指定getter来执行此操作:

NodeValidator get nodeValidator => new NodeValidatorBuilder()
..allowHtml5(uriPolicy: new ItemUrlPolicy());

正如您所看到的,我引用了一个UriPolicy,我将其保存在一个单独的文件中,例如uri_policy.dart:

import 'dart:html';

class ItemUrlPolicy implements UriPolicy {
  ItemUrlPolicy();

  RegExp regex = new RegExp(r'(?:http://|https://|//)?.*');

  bool allowsUri(String uri) {
    return regex.hasMatch(uri);
  }
}

在GünterZöchbauer和SO上其他有用帖子的作者的帮助下获得了很多帮助。