我正在使用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链接无法点击。
答案 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 中使用它并不能使链接正常工作,但是在单独的文件中使用它作为管道使这项工作变得很有吸引力。
这是我做的
.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}`);
}
}
}`
import { SafeDomPipe } from './pipes/safe.dom.pipe';
@NgModule({
imports: [
.....
],
exports: [
....
SafeDomPipe
....
],
declarations: [
....
SafeDomPipe
....
])
现在在 Html 中你可以直接使用这个管道。
<div [innerHtml]="data | safeDom: 'html' "> </div>
这将允许链接和样式。