angular - Angular 7:div innerHTML 绑定在有或没有对位置 html 数据进行 html 清理的情况下都不起作用
问题描述
我的数据源来自 REST 端点,它是一个 html 内容。获得数据后,我尝试将其放入 innerHTML 中,
<div [innerHTML]="mydata"></div>
但它不起作用。为了确保mydata
有数据,我尝试mydata
使用插值打印{{mydata}}
,它工作正常。然后我四处搜索,发现mydata
需要对其进行清理,因为出于安全考虑,Angular 不允许这样做。因此,我创建了一个管道,在其中使用它对其进行了消毒,
this.sanitizer.bypassSecurityTrustHtml(mydata)
但即使在此之后它也无法正常工作。
注意:我确实用简单的 HTML 内容尝试了相同的代码,它运行良好。mydata
在有问题的情况下有位置数据。
消毒代码:
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml, SafeStyle, SafeScript, SafeUrl,
SafeResourceUrl } from '@angular/platform-browser';
@Pipe({
name: 'safe'
})
export class SafePipe implements PipeTransform {
constructor(protected sanitizer: DomSanitizer) {}
public transform(value: any, type: string): SafeHtml | SafeStyle |
SafeScript | SafeUrl | SafeResourceUrl {
switch (type) {
case 'html': return this.sanitizer.bypassSecurityTrustHtml(value);
case 'style': return this.sanitizer.bypassSecurityTrustStyle(value);
case 'script': return this.sanitizer.bypassSecurityTrustScript(value);
case 'url': return this.sanitizer.bypassSecurityTrustUrl(value);
case 'resourceUrl': return this.sanitizer.bypassSecurityTrustResourceUrl(value);
default: throw new Error(`Invalid safe type specified: ${type}`);
}
然后我打电话给:
<div [innerHTML]="mydata | safe :'html'"></div>
根据@James Essex 的回答,我将代码修改为:
location.service.ts:从“rxjs”导入 { Observable }
getData(): Observable <any> {
return this.http.get(sourceUrl, { responseType: 'text'}).pipe(
tap(value => {
console.log(value);
})
);
}
component.ts `responseDataFromObservable: any; ngOnInit(){ this.callLocationData();
callLocationData() {
this.locationService.getData().subscribe(response => {
response = this.responseDataFromObservable;
})
}
}
而 html 是:正是@James Essex 所说的。
但仍然没有运气,UI 显示空白屏幕,没有任何错误。
解决方案
我认为您不应该尝试绕过安全性或将原始 HTML 注入<div [innerHTML]="myData">
. 这似乎直接违反了跨视域脚本的Angular 安全文档。
模板层使用 shadow DOM 不直接接触 HTML,并且可以通过Renderer2
.
我建议开发一个指令,而不是使用Renderer2
和ElementRef
:
例子:
角度指令:import { Directive, Renderer2, ElementRef, OnInit, Input } from '@angular/core';
@Directive({
selector: '[appSafeData]'
})
export class SafeDataDirective implements OnInit {
@Input passedHtmlData;
constructor(
private renderer: Renderer2,
private el: ElementRef,
) {}
ngOnInit() {
this.renderer.appendChild(this.el.nativeElement, passedHtmlData);
}
}
对应服务:
getData(): Observable<any> {
this.http.get('putUrlHere');
}
对应组件:
let responseDataFromObservable; // Put whatever type it is string, interfaced typings or any?
ngOnInit() {
callLocationData();
}
callLocationData() {
this.locationService.getData().subscribe(response => {
response = this.responseDataFromObservable;
}
}
对应的HTML:
<ng-container *ngIf="responseDataFromObservable">
<div appSafeData [passedHtmlData]="responseDataFromObservable" id="my-data-wrapper">
<!-- Your API data as HTML will be added here -->
</div>
</ng-container>
注意:我确信使用设置模板可能会更好,<ng-container>
但这样的方法是在不影响安全性的情况下注入数据的更好方法。
可能有帮助的其他链接:
推荐阅读
- firebase - 发送 Firebase 通知时,Axios 发布请求返回 403
- react-native - 如何在反应导航中隐藏标题?
- python - 删除空行后 Pandas 的数据框变为空
- firebase - 应用启动时 Firestore onSnapshot 未获取初始值
- lua - 是否可以对这串混淆的 Lua 代码进行反混淆?
- python - PyQt5 QUrl 在 QUrl.setUrl 之后为空
- reactjs - React Navigation 中的空白屏幕。反应原生
- bash - 为什么qrencode无法生成PNG图片
- javascript - 使用 Koa 和 Next JS 在本地开发 Shopify 应用程序时绕过 Shopify 身份验证?
- python - Docker 的 SSL 证书错误 - Flask 应用程序