Angular2 dynamically insert script tag

2019-01-14 19:16发布

I'm getting from server content into json object field, where it is html, <style></style> and <script></script> tags, and I want to execute it like this:

[innerHtml]="content | sanitize", but <script></script> tags do not execute. Is it possible to make it work?

My sanitize pipe looks like this:

import {Pipe} from '@angular/core';
import {DomSanitizationService} from '@angular/platform-browser';

@Pipe({
    name: 'sanitize',
    pure: true
})
export class Sanitize {
    constructor(private sanitizer: DomSanitizationService) {

    }

    transform(html: string) {

        return this.sanitizer.bypassSecurityTrustHtml(html);
    }
}

I know, that there is bypassSecurityTrustScript function in DomSanitizationService, but how can I use it in my case?

3条回答
混吃等死
2楼-- · 2019-01-14 19:42

It's not an angular 2's problem, script tags inserted via innerHTML are not executed.

If you have html string that contains script tags insert it this way:

const fragment = document.createRange().createContextualFragment(yourHtmlString);
anyElement.appendChild(fragment);
查看更多
地球回转人心会变
3楼-- · 2019-01-14 19:46

This will solve the issue...

import { Pipe } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({
  name: 'sanitize',
  pure: true
})
export class Sanitize {

  constructor(private domSanitizer: DomSanitizer) { }


  handleExternalScriptsInHtmlString(string) {
    let that = this;
    var parser = new DOMParser();
    var scripts = parser.parseFromString(string, 'text/html').getElementsByTagName('script');
    var results = [];

    for (var i = 0; i < scripts.length; i++) {
      var src = scripts[i].getAttribute('src');
      if (src.length && results.indexOf(src) === -1) {
        results.push(src);
        that.addScript(src);
      }
    }

    return results;
  }

  addScript(src) {
    var script = document.createElement('script');
    script.setAttribute('src', src);
    document.body.appendChild(script);
  }


  transform(htmlContent: any) {
    let sanitizeHtmlContent = this.domSanitizer.bypassSecurityTrustHtml(htmlContent);

    this.handleExternalScriptsInHtmlString(htmlContent);

    return sanitizeHtmlContent;
  }
}
查看更多
狗以群分
4楼-- · 2019-01-14 19:54

There is no angular way... You need to do it like this....

import { Pipe } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({
  name: 'sanitize',
  pure: true
})
export class Sanitize {

  constructor(private domSanitizer: DomSanitizer) { }


  handleExternalScriptsInHtmlString(string) {
    let that = this;
    var parser = new DOMParser();
    var scripts = parser.parseFromString(string, 'text/html').getElementsByTagName('script');
    var results = [];

    for (var i = 0; i < scripts.length; i++) {
      var src = scripts[i].getAttribute('src');
      if (src.length && results.indexOf(src) === -1) {
        results.push(src);
        that.addScript(src);
      }
    }

    return results;
  }

  addScript(src) {
    var script = document.createElement('script');
    script.setAttribute('src', src);
    document.body.appendChild(script);
  }


  transform(htmlContent: any) {
    let sanitizeHtmlContent = this.domSanitizer.bypassSecurityTrustHtml(htmlContent);

    this.handleExternalScriptsInHtmlString(htmlContent);

    return sanitizeHtmlContent;
  }
}
查看更多
登录 后发表回答