Angular 8使用[innerHTML]解析Azure blob存储TXT文件HTML无法正常渲染问题
问题原因
- HTML内容被二次转义
你从Azure Blob获取到的内容中存在&lt;这类双重转义字符,原本的<被转义为<后又被二次转义为&lt;,浏览器会将这类内容识别为普通文本而非HTML标签,所以直接渲染成转义后的代码文本。 - Angular默认安全策略拦截
Angular默认开启了XSS防护,所有通过[innerHTML]绑定的内容都会被自动清理,它会过滤掉所有被判定为不安全的标签、属性,即便你在元素检查窗口能看到原始内容,也会因为被安全策略拦截而无法正常渲染。 - 存储环节注入冗余标签
你管理模块使用的大概率是富文本编辑器,这类编辑器默认会给换行、空内容自动包裹<div><br></div>、<span>等标签,你在存储前没有做内容清理,直接将编辑器生成的带冗余标签的内容上传到了Blob,导致读取到的内容自带大量无关标签。
解决方案
- 第一步:处理HTML二次转义
拿到Blob返回的原始内容后,先做HTML实体解码,把双重转义的字符还原为正常的HTML标签,可使用以下工具函数:
decodeHtml(rawHtml: string): string { const textarea = document.createElement('textarea'); textarea.innerHTML = rawHtml; return textarea.value; }
- 第二步:绕过Angular安全拦截
注入Angular内置的DomSanitizer服务,将解码后的HTML内容标记为受信任的安全内容,示例代码:
import { Component } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; @Component({ // 你的组件配置 }) export class YourComponent { renderedHtml: SafeHtml; constructor(private sanitizer: DomSanitizer) {} // 处理从Blob拿到的原始内容 handleBlobContent(rawContent: string) { const decodedHtml = this.decodeHtml(rawContent); // 标记为安全HTML,绕过Angular默认清理逻辑 this.renderedHtml = this.sanitizer.bypassSecurityTrustHtml(decodedHtml); } private decodeHtml(rawHtml: string): string { const textarea = document.createElement('textarea'); textarea.innerHTML = rawHtml; return textarea.value; } }
模板绑定直接使用标记后的安全内容即可:
<div [innerHTML]="renderedHtml"></div>
- 第三步:从根源清理冗余标签
调整管理模块富文本编辑器的配置,关闭自动插入空div、span包裹换行的规则;也可以在上传内容到Azure Blob前,增加内容过滤逻辑,删除所有多余的空<div><br></div>等冗余标签后再存储。
内容的提问来源于stack exchange,提问作者armando t
相关产品推荐
相关产品推荐

