Angular 阻止模板中的脚本标签

Angular blocks script tags in template

我有一个来自后端的脚本标签:

<script>
(function(){
var a = document.createElement("script");
a.type="text/javascript";
a.src="https://someurl.js";
</script>

我想添加到 div 作为 innerHTML。

<div [innerHTML]="data"></div>

Angular 阻止它。解决方法是什么?

要在某些组件中输入 HTML,您必须使用 DomSanitizer,如下所示:

data:SafeHtml;
constructor(private sanitizer: DomSanitizer) { ... }

yourFunction() {
  this.data = this.sanitizer.bypassSecurityTrustHtml(YOUR_STRING_HTML)
}

在组件中是正确的。

<div [innerHTML]="data"></div>

你可以这样做。

const divEl = this.canvasElRef.nativeElement;

const scriptEl = this.renderer2.createElement('script');
    scriptEl.type = 'text/javascript';
    scriptEl.text = `
      (function() {
        console.log('console!')
      }());
    `;
    
this.renderer2.appendChild(divEl, scriptEl);

您可以使用 Angular 的 DomSanitizer 服务注入动态 HTML。 DomSanitizer 修改输入并转换为可以安全插入 DOM 的值。使用 bypassSecurityTrustHtml of DOMSanitizer 绕过此安全检查。

  trustedHtml: any;
  unsafeHtml: any;

  constructor(private domSanitizer: DomSanitizer) {
    this.unsafeHtml = `<script>
                        (function(){
                        var a = document.createElement("script");
                        a.type="text/javascript";
                        a.src="https://someurl.js";
                      </script>`;
    this.trustedHtml =    this.domSanitizer.sanitize(SecurityContext.HTML,this.domSanitizer.bypassSecurityTrustHtml(this.unsafeHtml));
  }
<div [innerHtml]="trustedHtml">  </div>

Live Example here

bypassSecurityTrustScript 不是 bypassSecurityTrustHtml

由于 following:

Angular 默认阻止此操作

Angular sanitizes untrusted values for HTML, styles, and URLs; sanitizing resource URLs isn't possible because they contain arbitrary code. In development mode, Angular prints a console warning when it has to change a value during sanitization.

这很重要,因为如果没有这个,不受信任的值可能会 运行 在我们的应用程序中,作为恶意脚本。这称为跨站点脚本攻击,攻击者会找到一种方法在应用程序中注入值。

如果您确定此端点只会return此脚本(如果您无法控制此端点,我会谨慎),然后使用DomSanitizer 方法通过 Angular:

绕过此默认行为
this.yourService().subscribe((script) => {
    this.script = this.sanitizer.bypassSecurityTrustScript(script);
});

这个方法 return 是一个 SafeScript,它告诉 Angular 它可以安全地用作 JavaScript。