首页 > 解决方案 > 如何在Angular应用程序中允许基本的自定义样式避免innerHTML

问题描述

我正在寻找针对特定案例的最佳(或至少是好的)实践。

我正在制作一个小型 Angular 应用程序,用户可以在其中添加文本。我希望他们能够将一些单词加粗或创建链接非常简单。因此,例如,当他们键入时,*whatever*它应该是粗体。所以现在我正在做的是:

问题是我不希望他们能够编写他们想要的任何 html。在这种情况下有没有办法避免使用 [innerHTML] ?

感谢您的时间。

标签: htmlangular

解决方案


允许用户输入任意文本并使用 innerHTML 显示它是危险的,并且确实需要您知道自己在做什么。

我想说你在这里最安全的选择(不使用innerHTML)是创建一个解析字符串的组件,将其分解为具有类型和内容的段,并动态放置模板,例如:

<ng-container *ngFor="let segment of segments">
  <span [ngSwitch]="segment.type">
    <ng-container *ngSwitchCase="'bold'"><b>segment.content</b></ng-container>
    <ng-container *ngSwitchCase="'link'"><a [href]="segment.data">segment.content</a></ng-container>
    <ng-container *ngSwitchDefault>segment.content</ng-container>
  </span>
</ng-container>

该模板可以扩展为处理斜体、下划线或其他。它存在一些问题(例如处理任何嵌套或多个标签),但都应该可以解决。

您的细分模型可能如下所示:

interface Segment {
  content: string;
  type: 'bold'|'text'|'link';
  data?: any;
}

然后你需要一些函数将你的字符串解析成这些段。在不了解您的案例的情况下很难说您的解析函数会是什么样子,但希望这能让您入门

一个可能更容易且仍然非常安全的次要选择是在根据您的自定义标记插入您自己的标签之前清理或转义您的字符串,这样您就可以安全地使用 innerHTML:

// inject the sanitizer
constructor(private sanitizer: DomSanitizer){ }

// run this on your string to remove unsafe text, then insert your marks so you can safely use innerHTML
sanitize(text: string) {
  return this.sanitizer.sanitize(SecurityContext.HTML, text);
}

消毒剂实际上会删除不安全的文本,但如果您想保留它并将其显示为文本,您也可以像这里的问题一样对其进行转义:Manually sanitize a string


推荐阅读