【问题标题】:Angular2 innerHtml binding remove style attribute [duplicate]Angular2 innerHtml绑定删除样式属性[重复]
【发布时间】:2017-01-30 09:07:24
【问题描述】:

我的问题是,当我使用 innererHtml 绑定时 - angular2 删除所有样式属性。这对我很重要,因为在我的任务中 - html 是在服务器端生成的,具有所有样式。 示例:

@Component({
  selector: 'my-app',
  template: `
    <input type="text" [(ngModel)]="html">
    <div [innerHtml]="html">
    </div>
  `,
})
export class App {
  name:string;
  html: string;
  constructor() {
    this.name = 'Angular2'
    this.html = "<span style=\"color:red;\">1234</span>";
  }
}

但在 DOM 中,我只看到 1234,而且这个文本不是红色的。

http://plnkr.co/edit/UQJOFMKl9OwMRIJ38U8D?p=preview

谢谢!

【问题讨论】:

    标签: angular styles


    【解决方案1】:

    您可以利用DomSanitized 来避免它。

    最简单的方法是创建自定义管道,例如:

    import { DomSanitizer } from '@angular/platform-browser'
    import { PipeTransform, Pipe } from "@angular/core";
    
    @Pipe({ name: 'safeHtml'})
    export class SafeHtmlPipe implements PipeTransform  {
      constructor(private sanitized: DomSanitizer) {}
      transform(value) {
        return this.sanitized.bypassSecurityTrustHtml(value);
      }
    }
    

    所以你可以像这样使用它:

    <div [innerHtml]="html | safeHtml"></div>
    

    Plunker Example

    【讨论】:

    • 很棒的解决方案!我唯一改变的是我将pure: true 添加到@Pipe 装饰器中,这样Angular 就知道不会在每次更改检测时一遍又一遍地重新计算它,并且只有在html(输入)是改变了。至少那是我认为应该发生的事情:)
    • 这会让你面临 XSS 攻击。
    • 绕过消毒剂以信任任何内容可能是一个安全问题。由于 Angular 不是一个专门的清理库,因此不冒任何风险对可疑内容过于热衷。例如,它删除了几乎所有属性。您可以将清理工作委托给一个专用库——DOMPurify。这是我制作的一个包装器库,可以轻松地将 DOMPurify 与 Angular 一起使用:github.com/TinkoffCreditSystems/ng-dompurify
    • 这会引起安全问题。在实施此解决方案之前,请阅读@a darren answer!
    • 管道名称应该是unsafeHtml,因为它实际上会让不安全的 html 进入 dom。此管道中没有任何 safe
    【解决方案2】:

    通过完成所需的导入,我稍微改进了 yurzui 的示例:

    import {DomSanitizer} from '@angular/platform-browser';
    import {PipeTransform, Pipe} from '@angular/core';
    
    @Pipe({ name: 'safeHtml'})
    export class SafeHtmlPipe implements PipeTransform  {
      constructor(private sanitized: DomSanitizer) {}
      transform(value) {
        return this.sanitized.bypassSecurityTrustHtml(value);
      }
    }
    

    我还必须在我的 app.module.ts 文件中添加该类

    import ...
    import {SafeHtmlPipe} from "./pipes/safehtml.pipe";
    @NgModule({
        declarations: [
            AppComponent,
            ...,
            SafeHtmlPipe  <--
        ],
        imports: [...],
        providers: [...],
        bootstrap: [AppComponent]
    })
    export class AppModule {
    }
    

    【讨论】:

      【解决方案3】:

      请注意,sanitizer 有一些信任内容的方法,例如

      this.sanitizer.bypassSecurityTrustStyle(value);
      this.sanitizer.bypassSecurityTrustHtml(value);
      this.sanitizer.bypassSecurityTrustXxx(value); // - see docs [1]
      

      通过https://stackoverflow.com/a/41089093/142714

      因此,bypassSecurityTrustStyle 也可能是您想要的,因为这将在您的 HTML 内容中显示内联样式 (value)。

      [1] 文档:https://angular.io/api/platform-browser/DomSanitizer

      【讨论】:

      • 我认为这应该是公认的答案。只有使用bypassSecurityTrustHtml() 才能运行恶意javascript。如果您只需要绕过样式,则使用bypassSecurityTrustStyle() 绕过会更好。
      • 这不应该是公认的答案,因为它是错误的。 bypassSecurityTrustStyle 返回 SafeStyle[innerHTML] 需要 SafeHtml。如果你使用它,它会抛出:Required a safe HTML, got a Style。因此,如果您的 html 内容具有内联样式,则应该采用外部清理程序和 bypassSecurityTrustHtml() 的组合,如下面的评论 (stackoverflow.com/questions/39628007/…) 中所述。
      猜你喜欢
      • 2017-02-09
      • 2012-08-12
      • 1970-01-01
      • 2017-11-17
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      • 2015-09-28
      • 1970-01-01
      相关资源
      最近更新 更多