带有超链接的Angular 5 DomSanitizer

时间:2017-12-13 08:45:56

标签: html angular hyperlink ckeditor

我正在使用WYSIWYG编辑器(CKEditor)并尝试使用Angular 5呈现内容。

我想弄清楚的是在Angular 5中使用DomSanitizer的正确方法。我面临的问题是超链接在生成的清理HTML中不起作用(不是“可点击的”)。

我使用以下的Typescript代码返回safeHtml内容:

 public getSafeContent(): SafeHtml {
    return this.sanitizer.bypassSecurityTrustHtml(this.page.content);
}

并以这种方式在我的模板中使用它:

<div [innerHTML]="getSafeContent()"></div>

这将呈现包含所有内联样式的HTML,但超链接将不起作用。

我尝试这样做:

public getSafeContent(): SafeHtml {
    return this.sanitizer.sanitize(SecurityContext.HTML, this.page.content);
}

这导致超链接实际上有效,但内联样式不是。

有没有办法让样式和超链接都能使用已清理的内容?

更新

这是Chrome开发工具中的页面:

<div _ngcontent-c22="" class="row">
   <div _ngcontent-c22="" class="col-lg-12">

        <div _ngcontent-c22="">
            <p><a href="http://www.google.com">google</a></p>
        </div>
    </div>
</div>

并且Google链接无法点击。

5 个答案:

答案 0 :(得分:1)

bypassSecurityTrustHtml允许内容中包含<script>个标记。对于您需要bypassSecurityTrustUrl的网址。见这里:https://angular.io/api/platform-browser/DomSanitizer#bypassSecurityTrustUrl

我从来没有尝试过堆叠bypassXXX方法,所以我不知道你是否可以做这样的事情bypassSecurityTrustUrl(bypassSecurityTrustHtml(myContent))但是我猜可能不会因为每个方法都需要string但返回一个对象(类型为SafeHtml/SafeUrl),因此它不能用作堆栈函数调用的输入,它需要一个字符串。

因此,您可能需要解析内容,将每个网址传递到bypassSecurityTrustUrl,然后将所有内容重新组合在一起。

<强>更新

我只是看了一下消毒方法。我没有试过这个,但这样的事情可能有用:

this.sanitizer.sanitize(SecurityContext.HTML, this.sanitizer.bypassSecurityTrustUrl(myContent));

因为sanitize可以将SafeValue作为输入。内部bypassSecurityTrustUrl清理URL并返回SafeUrl,它由外部清理打开并用作输入以使其安全。就像我说的那样,我还没有尝试过,但它在理论上看起来很不错......

答案 1 :(得分:0)

这对我有用:

组件:

content = '<b>Hello World</b><p style=\'font-size:14pt\'>
<a href=\'http://www.google.com\'>Go to Google</a></p>Test123';

public getSafeContent(): SafeHtml {
    return this.sanitizer.bypassSecurityTrustHtml(this.content);
}

HTML:

<div [innerHTML]="getSafeContent()"></div>

链接工作和内联样式完整

答案 2 :(得分:0)

.ts管道中的“ URL”消毒器

trans = as(data.frame,"transactions")

.html

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

@Pipe({ name: 'sanitizeUrl' })
export class SafeUrlPipe implements PipeTransform {
    constructor(private sanitizer: DomSanitizer) {}
    transform(url) {
        return this.sanitizer.bypassSecurityTrustResourceUrl(url);
    }
}

“ HTML”消毒剂管道

<div [innerHTML]="Content | sanitizeUrl| sanitizeHtml">
                    </div>

请考虑上述解决方案。这将同时应用两个管道,而不会干扰任何样式和链接点击事件

答案 3 :(得分:0)

我使用 DOMPurify 库来清理 DOM。 DOMPurify 是一个仅限 DOM、超快、超容忍的 XSS 清理器,适用于 HTML、MathML 和 SVG。

我创建了有角度的 PureTextPipe 管道来清理原始内容

import { Pipe, PipeTransform } from '@angular/core';
import DOMPurify from 'dompurify';

@Pipe({
  name: 'pureText',
  pure: true
})
export class PureTextPipe implements PipeTransform {

  transform(str: any): any {
    let res = str;
    if (str === null || str === undefined || str === '' || str === 0) {
      res = '--';
    }
    return DOMPurify.sanitize(res);
  }
}

现在要使用此管道,您只需要将其添加到 HTML 中,例如:

<div [innerHTML]="yourRawData | pureText"></div>

DOMPurify 的文档

https://www.npmjs.com/package/dompurify

import DOMPurify from 'dompurify';

var clean = DOMPurify.sanitize(dirty);

答案 4 :(得分:0)

我找到了一个可行的解决方案。有了这个,URL 和样式都可以工作。再次使用“bypassSecurityTrustHtml”。令人惊讶的是,在 html 或 TS 中使用它并不能使链接正常工作,但是在单独的文件中使用它作为管道使这项工作变得很有吸引力。

这是我做的

  1. 创建自定义管道

.safe.dom.pipe

import { Component, Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml, SafeResourceUrl, SafeScript, SafeStyle, SafeUrl } from '@angular/platform-browser'; 
@Pipe({
name: 'safeDom'
 })
export class SafeDomPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {}
public transform(value: any, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
    switch (type) {
            case 'html': return this.sanitizer.bypassSecurityTrustHtml(value);
            case 'style': return this.sanitizer.bypassSecurityTrustStyle(value);
            case 'script': return this.sanitizer.bypassSecurityTrustScript(value);
            case 'url': return this.sanitizer.bypassSecurityTrustUrl(value);
            case 'resourceUrl': return this.sanitizer.bypassSecurityTrustResourceUrl(value);
            default: throw new Error(`Invalid safe type specified: ${type}`);
        }
  }
}`
  1. 如果您的项目中有一个公共模块包含在您需要实现它的地方,您可以从那里声明和导出此包。否则只需在要实现此功能的模块中声明此管道。
<块引用>
  import { SafeDomPipe } from './pipes/safe.dom.pipe';
    @NgModule({
        imports: [
            .....
        ],
        exports: [
          ....
          SafeDomPipe 
          ....
        ],
        declarations: [
          ....
          SafeDomPipe 
          ....
        ])

现在在 Html 中你可以直接使用这个管道。

<div [innerHtml]="data | safeDom: 'html' "> </div>

这将允许链接和样式。