我正在写一个Angular应用程序,我有一个HTML响应,我想显示。
我怎么做呢?如果我简单地使用绑定语法{{myVal}},它将编码所有HTML字符(当然)。
我需要以某种方式将一个div的innerHTML绑定到变量值。
我正在写一个Angular应用程序,我有一个HTML响应,我想显示。
我怎么做呢?如果我简单地使用绑定语法{{myVal}},它将编码所有HTML字符(当然)。
我需要以某种方式将一个div的innerHTML绑定到变量值。
当前回答
如果[innerHTML]包含用户创建的内容,直接使用[innerHTML]而不使用Angular的DOM消毒器是不可取的。@GünterZöchbauer在他的回答中建议的safeHtml管道是一种净化内容的方法。下面的指令是另一个指令:
import { Directive, ElementRef, Input, OnChanges, Sanitizer, SecurityContext,
SimpleChanges } from '@angular/core';
// Sets the element's innerHTML to a sanitized version of [safeHtml]
@Directive({ selector: '[safeHtml]' })
export class HtmlDirective implements OnChanges {
@Input() safeHtml: string;
constructor(private elementRef: ElementRef, private sanitizer: Sanitizer) {}
ngOnChanges(changes: SimpleChanges): any {
if ('safeHtml' in changes) {
this.elementRef.nativeElement.innerHTML =
this.sanitizer.sanitize(SecurityContext.HTML, this.safeHtml);
}
}
}
被使用
<div [safeHtml]="myVal"></div>
其他回答
正确的语法如下:
<div [innerHTML]="theHtmlString"></div>
文档参考
如果我错过了重点,我很抱歉,但我想推荐一种不同的方法:
我认为最好从服务器端应用程序返回原始数据,并将其绑定到客户端模板。这使得请求更加灵活,因为您只从服务器返回json。
对我来说,如果你所做的只是从服务器获取html并将其“原样”注入到DOM中,那么使用Angular似乎没有意义。
我了解Angular 1。x有一个html绑定,但我在Angular 2.0中还没有看到对应的绑定。不过他们以后可能会加进去。不管怎样,我还是会考虑为你的Angular 2.0应用提供一个数据api。
如果您感兴趣的话,这里有一些带有简单数据绑定的示例:http://www.syntaxsuccess.com/viewarticle/angular-2.0-examples
如果[innerHTML]包含用户创建的内容,直接使用[innerHTML]而不使用Angular的DOM消毒器是不可取的。@GünterZöchbauer在他的回答中建议的safeHtml管道是一种净化内容的方法。下面的指令是另一个指令:
import { Directive, ElementRef, Input, OnChanges, Sanitizer, SecurityContext,
SimpleChanges } from '@angular/core';
// Sets the element's innerHTML to a sanitized version of [safeHtml]
@Directive({ selector: '[safeHtml]' })
export class HtmlDirective implements OnChanges {
@Input() safeHtml: string;
constructor(private elementRef: ElementRef, private sanitizer: Sanitizer) {}
ngOnChanges(changes: SimpleChanges): any {
if ('safeHtml' in changes) {
this.elementRef.nativeElement.innerHTML =
this.sanitizer.sanitize(SecurityContext.HTML, this.safeHtml);
}
}
}
被使用
<div [safeHtml]="myVal"></div>
[innerHtml]在大多数情况下是一个很好的选择,但当你需要在html中硬编码样式时,它会失败。
我想分享其他方法:
你所需要做的就是在你的html文件中创建一个div,并给它一个id:
<div #dataContainer></div>
然后,在你的Angular 2组件中,创建对这个对象的引用(这里是TypeScript):
import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
templateUrl: "some html file"
})
export class MainPageComponent {
@ViewChild('dataContainer') dataContainer: ElementRef;
loadData(data) {
this.dataContainer.nativeElement.innerHTML = data;
}
}
然后简单地使用loadData函数将一些文本附加到html元素。
这只是一种使用原生javascript的方式,但在Angular环境中。我不推荐这样做,因为这会使代码更加混乱,但有时也没有其他选择。
另见Angular 2 - innerHTML样式
这里已经提供了简短的回答:使用<div [innerHTML]="yourHtml">绑定。
然而,这里提到的其他建议可能具有误导性。当你绑定到这样的属性时,Angular有一个内置的清除机制。因为Angular不是一个专门的消毒库,所以它对可疑内容过于热心,不愿冒任何风险。例如,它将所有SVG内容清除为空字符串。
您可能会听到一些建议,通过使用DomSanitizer将内容标记为安全的bypassSecurityTrustXXX方法来“消毒”您的内容。也有使用管道的建议,该管道通常被称为safeHtml。
所有这些都是误导,因为它实际上绕过了消毒,而不是消毒你的内容。这可能是一个安全问题,因为如果您对用户提供的内容或任何您不确定的内容这样做,您就会为恶意代码攻击敞开大门。
如果Angular通过内置的清理功能删除了你需要的某些东西,你可以做的不是禁用它,而是将实际的清理工作委托给擅长这项任务的专用库。例如——DOMPurify。
我已经为它做了一个包装器库,这样就可以很容易地在Angular中使用它: https://github.com/TinkoffCreditSystems/ng-dompurify
它还有一个管道来声明式地净化HTML:
<div [innerHtml]="value | dompurify"></div>
与这里建议的管道的不同之处在于,它实际上通过DOMPurify进行消毒,因此适用于SVG。
编辑:Angular不再在Ivy渲染器中对CSS进行消毒,所以下面的信息(出于历史考虑)是不相关的:
要记住的一件事是,DOMPurify很适合净化HTML/SVG,但不适用于CSS。所以你可以提供Angular的CSS消毒器来处理CSS:
import {NgModule, ɵ_sanitizeStyle} from '@angular/core';
import {SANITIZE_STYLE} from '@tinkoff/ng-dompurify';
@NgModule({
// ...
providers: [
{
provide: SANITIZE_STYLE,
useValue: ɵ_sanitizeStyle,
},
],
// ...
})
export class AppModule {}
它是内部的——因此有了ɵ前缀,但这也是Angular团队在他们自己的包中使用它的方式。该库也适用于Angular Universal和服务器端渲染环境。