使用 DomSanitizer 绕过安全性后,安全值必须使用 [property]=binding
Posted
技术标签:
【中文标题】使用 DomSanitizer 绕过安全性后,安全值必须使用 [property]=binding【英文标题】:Safe value must use [property]=binding after bypass security with DomSanitizer 【发布时间】:2018-01-03 05:18:41 【问题描述】:<!--html CODE-->
<p #mass_timings></p>
//Controller code
@ViewChild('mass_timings') mass_timings: ElementRef;
constructor(private domSanitizer:DomSanitizer)
getInnerHTMLValue()
this.mass_timings.nativeElement.innerHTML =
this.domSanitizer.bypassSecurityTrustHtml(this.parishDetail.mass_timings);
但 mass_timings 显示的输出包括文本:-
安全值必须使用 [property]=binding
开头
如何删除这个字符串。
【问题讨论】:
【参考方案1】:正如错误消息所说,需要使用属性绑定添加经过清理的 HTML:
<p [innerHTML]="massTimingsHtml"></p>
constructor(private domSanitizer:DomSanitizer)
this.massTimingsHtml = this.getInnerHTMLValue();
getInnerHTMLValue()
return this.domSanitizer.bypassSecurityTrustHtml(this.parishDetail.mass_timings);
StackBlitz example(基于 Swapnil Patwa 的 Plunker - 请参阅下面的 cmets)
【讨论】:
@manish kumar,演示插件 - plnkr.co/edit/oCZ9yKTl68kuTPx6s7fH?p=preview 只这样做了。但是你能联系this并解释一下吗 您可以这样做,但不能使用经过净化的 HTML,只能使用纯 HTML 字符串。 如果您使用this.mass_timings.nativeElement.innerHTML = ...
,则不会。但出于安全原因,建议进行消毒。
@manishkumar 大多数情况下,将 Plunkers 代码复制到 StackBlitz 即可解决此问题。基于旧 Angular 版本的 Plunker 不再运行。请参阅我更新的答案中的 StackBlitz。【参考方案2】:
您需要像这样 sanitize() 安全值:
this.domSanitizer.sanitize(SecurityContext.HTML,this.domSanitizer.bypassSecurityTrustHtml(this.parishDetail.mass_timings));
【讨论】:
你不只是重新消毒吗? 我猜 sanitize() 只发生一次。它有效,这就是我发布的原因。 看起来很有趣,但这确实有效!而且它更好,因为您不需要在任何地方绑定到 [innerHtml]。【参考方案3】:我在使用 iframe 时遇到此错误,因此我使用[src]
进行了修复,如下所示:
注意:使用管道获得更好的性能
导入:
import DomSanitizer, SafeHtml from '@angular/platform-browser';
constructor(private sanitizer: DomSanitizer, ....other DI)
在ts文件中
getSafeUrl()
return this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
在 html 文件中
<iframe [src]="getSafeUrl()" frameborder="0" *ngIf="url"></iframe>
此方法非常耗时,因为它会多次调用该函数,因此最好在 lifeCycleHooks 中清理 URL,例如 ngOnInit()
。
您也可以使用管道来获得更好的性能:
使用管道
HTML:
<iframe [src]="url | byPassSecurity"></iframe>
Sanitize.pipe.ts:
import Pipe, PipeTransform, SecurityContext from "@angular/core";
import DomSanitizer, SafeHtml from '@angular/platform-browser';
@Pipe(
name: 'byPassSecurity'
)
export class ByPassSecurityPipe implements PipeTransform
constructor(private sanitizer: DomSanitizer)
transform (value: string): SafeHtml
return this.sanitizer.bypassSecurityTrustHtml(value);
【讨论】:
您节省了我的时间,谢谢! src="code" 不起作用,但 [src]="code" 就像一个魅力! 经过数小时的尝试,终于找到了适合我的解决方案。有人知道为什么src="code"
不起作用但[src]="code"
起作用吗?
您应该使用管道而不是函数来节省性能并防止每次更改检测运行时调用它。请参阅 Renil Babu 的答案。【参考方案4】:
我使用 Pipe 的解决方案。
HTML
<div [innerHtml]="htmlValue | byPassSecurity"></div>
管道
import Pipe, PipeTransform, SecurityContext from "@angular/core";
import DomSanitizer, SafeHtml from '@angular/platform-browser';
@Pipe(
name: 'byPassSecurity'
)
export class ByPassSecurityPipe implements PipeTransform
constructor(private sanitizer: DomSanitizer)
transform (value: string): SafeHtml
return this.sanitizer.bypassSecurityTrustHtml(value);
【讨论】:
管道是性能方面的最佳解决方案,因为每次更改检测运行时都会调用一个函数(如 Black Mamba 所说)。【参考方案5】:我在角度 7 中使用 MATHJAX 时遇到了同样的错误。我通过下面的管道变换解决了。 100% 完美运行
//清理HTML PIPE
import Pipe, PipeTransform, SecurityContext from "@angular/core";
import DomSanitizer, SafeHtml from '@angular/platform-browser';
@Pipe(
name: 'sanitizeHtml'
)
export class SanitizeHtmlPipe implements PipeTransform
constructor(private _sanitizer: DomSanitizer)
transform(value: string): SafeHtml
return this._sanitizer.sanitize(SecurityContext.HTML, this._sanitizer.bypassSecurityTrustHtml(value))
【讨论】:
为什么要强调消毒剂?没有意义。您还说它可以 100% 完美运行,但并非如此,其他一些人可能会使用SecurityContext.URL
,例如取决于上下文。
如何应用相同的元素标题【参考方案6】:
你不需要到处绑定[innerHtml]
。
它可以像这样一起使用sanitize()
和bypassSecurityTrustHtml()
工作:
this.mass_timings.nativeElement.innerHTML = (
this.domSanitizer.sanitize(SecurityContext.HTML, this.domSanitizer.bypassSecurityTrustHtml(this.parishDetail.mass_timings))
);
【讨论】:
以上是关于使用 DomSanitizer 绕过安全性后,安全值必须使用 [property]=binding的主要内容,如果未能解决你的问题,请参考以下文章