1.背景javascript
在最近angular的項目中,須要用到[innerHTML]標籤來指定一個div的樣式: html
1 //HTML部分 2 <div class="contents" [innerHTML]="contents"></div> 3 4 //TS部分 5 contents = '<p>商品信息欄位<br><span style="color:red;">商品信息介紹</span></p>';
可是上面的樣式並不起做用,在Chorme中查看源碼,發現style標籤的樣式在Angular編譯的時候被屏蔽掉。這是爲何呢?客觀別急,請往下看。java
2.解決方案api
先說解決方案,最後再分析出現這種問題的緣由。修改上面的TS:安全
// 在使用的頁面引入DomSanitizer import { DomSanitizer } from '@angular/platform-browser'; //構造方法裏注入sanitizer對象 constructor( private sanitizer: DomSanitizer ) { } // 對HTML代碼作處理 this.contents= this.sanitizer.bypassSecurityTrustHtml("<p>W3商品信息欄位<br><span style="color:red;">商品信息介紹</span></p>");
這樣雖然能夠解決問題,可是這樣作還不夠:優化
基於以上兩點,咱們用自定義管道(pipe)來優化以上代碼,使用ng generate pipe safe-html命令來生成一個pipe,並作適當的修改:this
// 對safe-html.pipe.ts作適當修改
import {Pipe, PipeTransform} from '@angular/core'; import {DomSanitizer} from '@angular/platform-browser'; @Pipe({name: 'safeHtml'}) export class SafeHtmlPipe implements PipeTransform { constructor(private sanitized: DomSanitizer) { } transform(value) { return this.sanitized.bypassSecurityTrustHtml(value); } }
// 在使用innerHTML標籤的屬性裏使用以上safeHtml管道
<div class="contents" [innerHTML]="contents|safeHtml"></div>
3.緣由及原理spa
因此,爲何會出現上面的問題呢?原來,Angular中默認將全部輸入值視爲不受信任。當咱們經過 property,attribute,樣式,類綁定或插值等方式,3d
將一個值從模板中插入到DOM中時,Angular會自幫咱們清除和轉義不受信任的值。在開頭的例子中,span標籤裏的樣式被屏蔽了,不信請看:code
Angular 在編譯的時候,會自動清理 HTML 輸入並轉義不安全的代碼,所以在這種狀況下,style被屏蔽,樣式失效。這時候若是須要將樣式片斷渲染出來,
就須要用到DomSanitizer了。DomSanitizer 能夠把值淨化爲在不一樣 DOM 上下文中的安全內容,來幫咱們防範跨站腳本攻擊(XSS)類的安全問題。
參考:https://angular.cn/api/platform-browser/DomSanitizer#description