允许用户输入任意文本并使用 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