web-dev-qa-db-ja.com

Angular 5ハイパーリンク付きDomSanitizer

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>

そしてグーグルリンクはクリックできません。

7
user2845798

bypassSecurityTrustHtmlは、コンテンツに_<script>_タグを許可します。 URLの場合、bypassSecurityTrustUrlが必要です。ここを参照してください: https://angular.io/api/platform-b​​rowser/DomSanitizer#bypassSecurityTrustUrl

bypassXXXメソッドをスタックしようとしたことがないので、このbypassSecurityTrustUrl(bypassSecurityTrustHtml(myContent))のようなことができるかどうかはわかりませんが、各メソッドは文字列を受け取りますが、オブジェクト(タイプ_SafeHtml/SafeUrl_)であるため、文字列を必要とするスタック関数呼び出しへの入力として使用することはできません。

そのため、コンテンツを解析し、各URLをbypassSecurityTrustUrlに渡してから、すべてを再び結合する必要がある場合があります。

更新

消毒方法を見たところです。私はこれを試していませんが、次のようなものが機能する可能性があります。

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

sanitizeSafeValueを入力として受け取ることができるためです。内部のbypassSecurityTrustUrlはURLをサニタイズし、SafeUrlを返します。これは、外部のサニタイズによってラップ解除され、HTMLセーフにするための入力として使用されます。私が言ったように、私はそれを試していませんが、理論的には良さそうです...

2
TimTheEnchanter

'URL'サニタイザー用の.tsパイプ内

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>

「HTML」サニタイザー用パイプ

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

@Pipe({
    name: 'sanitizeHtml'
})
export class SafeHtmlPipe implements PipeTransform {
    constructor(private sanitized: DomSanitizer) {}
    transform(value) {
        return this.sanitized.bypassSecurityTrustHtml(value);
    }
}

上記の解決策を検討してください。これにより、スタイルとリンククリックイベントを同時に妨げることなく、両方のパイプが適用されます。

1
Sahil Ralkar

これは私のために働きます:

成分:

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>

リンク作品とインラインスタイルはそのままです

0
TimTheEnchanter