Angular2动态插入脚本标签

Posted

技术标签:

【中文标题】Angular2动态插入脚本标签【英文标题】:Angular2 dynamically insert script tag 【发布时间】:2017-01-21 05:35:58 【问题描述】:

我正在从服务器内容获取到 json 对象字段,它是 html<style></style><script></script> 标记,我想像这样执行它:

[innerHtml]="content | sanitize",但<script></script> 标签不执行。有没有可能让它发挥作用?

我的消毒管道如下所示:

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);
    

我知道,DomSanitizationService 中有 bypassSecurityTrustScript 功能,但我该如何使用呢?

【问题讨论】:

json对象长什么样子?你想转换什么? html 是否添加到 DOM 中?您是否在浏览器控制台中收到错误消息? 内容如下所示:"some html " 不执行 Html 正确添加到 dom 【参考方案1】:

这将解决问题...

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;
  

【讨论】:

【参考方案2】:

没有角度的方式......你需要这样做......

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;
  

【讨论】:

这也有同样的问题,对吧?因为你仍然只是得到一个你必须使用不执行脚本标签的 innerHtml 显示的变量 @SeanKPS 没有这个实际上会执行脚本标签。注意函数 addScript。我们正在手动查找脚本标签并将它们显式添加到 DOM 我认为 Angular 根本不会执行脚本标签——即使它们在 DOM 中。也许这仅在组件模板中,并且在直接附加到正文时不适用。尽管如此,我还是需要将脚本输出准确地放在 DOM 中脚本标记的位置,对于 Github Gists,我最终编写了几个函数来对其进行排序。【参考方案3】:

不是angular 2的问题,通过innerHTML插入的script标签没有被执行。

如果您的 html 字符串包含 script 标记,请以这种方式插入:

const fragment = document.createRange().createContextualFragment(yourHtmlString);
anyElement.appendChild(fragment);

【讨论】:

完美运行 对于其他可能需要在某些时候向正文添加脚本,但故意不希望它在初始页面加载时与应用程序的其余部分一起引导的其他人:document.body.appendChild(fragment) 也可以工作Alex 的代码的第二行,而不是在 Angular 中设置 ViewChild。

以上是关于Angular2动态插入脚本标签的主要内容,如果未能解决你的问题,请参考以下文章

如何将第 3 方脚本从 Web 动态加载到 Angular2 组件中

Angular2动态组件和TP jQuery库

Angular2 DynamicContentLoader 将元素插入到目标容器的顶部

Angular2 [innerHtml] angular2 标签不起作用

Angular2 - 用 html 插入字符串

使用 Angular 2 的动态标签导航系统