作用
DomSanitizer有助于防止跨站点脚本安全漏洞(XSS),通过清除值以便在不同的DOM上下文中安全使用。
为什么会需要使用DomSanitizer
Angular4中默认将所有输入值视为不受信任。当我们通过 property,attribute,样式,类绑定或插值等方式,将一个值从模板中插入到DOM中时,Angular4会自帮我们清除和转义不受信任的值。
如下有个例子:
domsan-test.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-domsan-test',
templateUrl: './domsan-test.component.html'
})
export class DomsanTestComponent {
html='<h1>哈哈哈哈哈哈<h1><script>attackerCode()</script>';
}
domsan-test.component.html
<div>{{html}}</div>
结果:Angular4 在编译的时候,会自动清理 HTML 输入并转义不安全的代码,因此在这种情况下,这个html代码片段被当成了字符串,只能在屏幕上显示为文本。
这时候如果需要将html代码片段渲染出来,就需要用到DomSanitizer了。
方法
abstract class DomSanitizer implements Sanitizer {abstract sanitize(context: SecurityContext, value: SafeValue | string | null): string | null
abstract bypassSecurityTrustHtml(value: string): SafeHtml
abstract bypassSecurityTrustStyle(value: string): SafeStyle
abstract bypassSecurityTrustScript(value: string): SafeScript
abstract bypassSecurityTrustUrl(value: string): SafeUrl
abstract bypassSecurityTrustResourceUrl(value: string): SafeResourceUrl
下面将使用例子来了解如何使用这几个方法。
1. bypassSecurityTrustHtml
domsan-test.component.ts
import { Component, OnInit} from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Component({
selector: 'app-domsan-test',
templateUrl: './domsan-test.component.html'
})
export class DomsanTestComponent implements OnInit {
html='<h1>哈哈哈哈哈哈<h1><script>attackerCode()</script>';
shtml: SafeHtml;
constructor(private sanitizer: DomSanitizer) { }
ngOnInit() {
this.shtml =this.sanitizer.bypassSecurityTrustHtml(this.html);
}
}
domsan-test.component.html
<div [innerHTML]="shtml"></div>
结果:
注:插入方式不可以是插值法直接插入,必须是属性绑定的形式插入。
如果以下面的方式插入,是错误的方式。
<div>{{shtml}}</div>
结果:
bypassSecurityTrustStyle,bypassSecurityTrustScript,bypassSecurityTrustUrl,bypassSecurityTrustResourceUrl的使用方式与bypassSecurityTrustHtml类似。
属性绑定的形式分别是:
<!-- bypassSecurityTrustStyle -->
<div [style]="sstyle"></div>
<!-- bypassSecurityTrustUrl -->
<div > <img [src]="aa"></div>
<!-- bypassSecurityTrustResourceUrl -->
<iframe [src]="surl"></iframe>
2. sanitize
有时后我们需要手动过滤输入值,这时可以使用 sanitize 方法
this.html = this.sanitizer.sanitize(SecurityContext.HTML,this.html);
console.log(this.html);
控制台输出:
WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).
domsan-test.component.ts:24 <h1>哈哈哈哈哈哈</h1><h1>attackerCode()</h1>
3.自定义指令
为了更方面的在项目中使用,可自定义一个pipe。
keepHtml.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({ name: 'keepHtml', pure: false })
export class EscapeHtmlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {
}
transform(content) {
return this.sanitizer.bypassSecurityTrustHtml(content);
}
}
html
<div [innerHTML]="html | keepHtml"></div>
使用pipe要在所在的module.ts中声明这个指令并导入
import {EscapeHtmlPipe} from './domsan-test/keepHtml.pipe';
@NgModule({
declarations: [
EscapeHtmlPipe
],
imports: [
]
})
export class DemoModule { }
当使用bypassSecurityTrust …时,确保尽可能早地调用方法并尽可能接近值的来源,以便于验证它的使用是否会产生安全错误。
等有空再详细补充吧。。
参考链接:
https://angular.cn/api/platform-browser/DomSanitizer
https://blog.csdn.net/qq_34645412/article/details/79002099
https://segmentfault.com/a/1190000008809095