Angular中渲染TS数组内SVG图标失败,innerHTML失效如何解决?
修复Angular中用[innerHTML]显示SVG图标失效的问题
问题原因
- 你的SVG字符串是转义后的HTML(比如用
<代替<、"代替"),浏览器会把这些转义字符当作普通文本渲染,不会解析为SVG元素。 - Angular的安全机制(DomSanitizer)会自动净化未标记为安全的HTML内容,防止XSS攻击,直接用
[innerHTML]插入会被过滤。
解决方案
步骤1:还原SVG字符串的转义字符
把数组中svgPath里的转义符号替换为正常HTML标签:
<→<>→>"→"
步骤2:用DomSanitizer标记SVG为安全内容
通过Angular的DomSanitizer服务,把SVG字符串标记为可信任的HTML,避免被安全机制过滤。
方法1:组件内创建处理方法
修改组件代码:
import { Component } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; interface IInstagramIcons { name: string; svgPath: string; } @Component({ selector: 'app-sidenav', templateUrl: './sidenav.component.html', styleUrls: ['./sidenav.component.css'] }) export class SidenavComponent { sideBarIcons: IInstagramIcons[] = [ { name: 'Home', svgPath: '<svg aria-label="Home" class="x1lliihq x1n2onr6 x5n08af" fill="currentColor" height="24" role="img" viewBox="0 0 24 24" width="24"><title>Home</title><path d="M9.005 16.545a2.997 2.997 0 0 1 2.997-2.997A2.997 2.997 0 0 1 15 16.545V22h7V11.543L12 2 2 11.543V22h7.005Z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="2"></path></svg>' }, { name: 'Search', svgPath: '<svg aria-label="Search" class="x1lliihq x1n2onr6 x5n08af" fill="currentColor" height="24" role="img" viewBox="0 0 24 24" width="24"><title>Search</title><path d="M19 10.5A8.5 8.5 0 1 1 10.5 2a8.5 8.5 0 0 1 8.5 8.5Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path><line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="16.511" x2="22" y1="16.511" y2="22"></line></svg>' }, ]; constructor(private sanitizer: DomSanitizer) {} // 处理SVG内容为安全HTML getSafeSvg(html: string): SafeHtml { return this.sanitizer.bypassSecurityTrustHtml(html); } }
模板中调用该方法:
<nav class="vertical-sidenav-left bg-black w-80 p-10"> <div class="text-white"> <ul> @for (icon of sideBarIcons; track icon.name){ <div>{{icon.name}}</div> <div [innerHTML]="getSafeSvg(icon.svgPath)"></div> } </ul> </div> </nav>
方法2:创建复用管道(推荐)
如果多个组件需要处理安全HTML,创建自定义管道更高效:
- 创建
SafeHtmlPipe管道:
import { Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @Pipe({ name: 'safeHtml' }) export class SafeHtmlPipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(value: string): SafeHtml { return this.sanitizer.bypassSecurityTrustHtml(value); } }
- 在模块中声明管道:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { SafeHtmlPipe } from './safe-html.pipe'; import { SidenavComponent } from './sidenav.component'; @NgModule({ declarations: [ SidenavComponent, SafeHtmlPipe ], imports: [BrowserModule], bootstrap: [SidenavComponent] }) export class AppModule {}
- 模板中使用管道:
<nav class="vertical-sidenav-left bg-black w-80 p-10"> <div class="text-white"> <ul> @for (icon of sideBarIcons; track icon.name){ <div>{{icon.name}}</div> <div [innerHTML]="icon.svgPath | safeHtml"></div> } </ul> </div> </nav>
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

