我试图从数据库中获取第三方(可能不安全)html内容,并将其插入html文档.

我如何安全地做到这一点(防止XSS)?

Angular1.x中,曾经有$sce个用于消毒输入,在Angular2中,我该怎么做?据我所知,Angular2在默认情况下会自动对其进行消毒,对吗?

这样的事情是行不通的:

<div class="foo">
    {{someBoundValueWithSafeHTML}} // I want HTML from db here
</div>

推荐答案

要将普通HTML插入angular2应用程序,可以使用[innerHtml]指令.

<div [innerHtml]="htmlProperty"></div>

这不适用于HTML,因为它有自己的组件和指令,至少不符合您的预期.

然而,如果你确实收到了一个不安全的html警告,你应该在注射之前首先信任HTML.你必须用DomSanitizer来做这样的事.例如,<h3>元素被认为是安全的.<input>元素不是.

export class AppComponent  {

    private _htmlProperty: string = '<input type="text" name="name">';

    public get htmlProperty() : SafeHtml {
       return this.sr.bypassSecurityTrustHtml(this._htmlProperty);
    }

    constructor(private sr: DomSanitizer){}
}

让你的模板保持不变:

<div [innerHtml]="htmlProperty"></div>

不过要注意一点:

警告:使用不受信任的用户数据调用此方法会使您的应用程序面临XSS安全风险!

如果你打算更多地使用这种技术,你可以试着写一个@Pipe来完成这项任务.

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Pipe({
    name: 'trustHtml'
})
export class TrustHtmlPipe implements PipeTransform  {    
   constructor(readonly sr: DomSanitizer){}  

   transform(html: string) : SafeHtml {
      return this.sr.bypassSecurityTrustHtml(html); 
   } 
} 

如果你有这样一根管子,你的AppComponent会变成这个.不要忘记将管道添加到NgModule的声明数组中:

@Component({
   selector: 'app',
   template: `<div [innerHtml]="htmlProperty | trustHtml"></div>`
})
export class AppComponent{

    public htmlProperty: string = '<input type="text" name="name">';

} 

或者你也可以写一个@Directive来做同样的事情:

@Directive({
   selector: '[trustHtml]'
})
export class SanitizeHtmlDirective {

    @Input()
    public set trustHtml(trustHtml: string) {
      if (this._trustHtml !== trustHtml) {
        this._trustHtml = trustHtml;
        this.innerHtml = this.sr.bypassSecurityTrustHtml(this.trustHtml);
      }
    }

    @HostBinding('innerHtml')
    innerHtml?: SafeHtml;

    private _trustHtml: string;

    constructor(readonly sr: DomSanitizer){}
}

如果你有这样的指令,你的AppComponent会变成这个.不要忘记将指令添加到NgModule的声明数组中:

@Component({
   selector: 'app',
   template: `<div [trustHtml]="htmlProperty"></div>`
})
export class AppComponent{

    public htmlProperty: string = '<input type="text" name="name">';

} 

Typescript相关问答推荐

需要使用相同组件重新加载路由变更数据—React TSX

Webpack说你可能需要在Reactjs项目中增加一个加载器''

创建一个根据布尔参数返回类型的异步函数

如何实现异构数组内函数的类型缩小

ApexCharts条形图未显示最小值.负值

AngularJS服务不会解析传入的Json响应到管道中的模型

将带点的对象键重新映射为具有保留值类型的嵌套对象

Angular 自定义验证控件未获得表单值

复选框Angular 在Ngfor中的其他块中重复

如何为特定参数定义子路由?

map 未显示控制台未显示任何错误@reaction-google-map/api

如何在Reaction 18、Reaction-Rout6中的导航栏中获取路由参数

如何静态键入返回数组1到n的函数

TypeScrip:使用Cypress测试包含插槽的Vue3组件

TypeScrip:从嵌套的对象值创建新类型

如何使对象同时具有隐式和显式类型

显式推断对象为只读

类型string不可分配给类型string| 联盟| 的'

如何编写一个接受 (string|number|null|undefined) 但只返回 string 且可能返回 null|undefined 的函数?

具有来自其他类型的修改键名称的 TypeScript 通用类型