javascript - Angular 2如何从innerHTML执行脚本标签

标签 javascript http angular

我已经通过 http.get() 方法加载了 HTML 页面,并将此页面的内容添加到 div 标签。

getRequestToAssignPage (param: string) : any {

    return this.$http.get(param)
        .map((res: Response) => {

            this.status = res;

            return res.text();
        })
        .toPromise()
        .then(response => {



            let restr: string = response;



            restr = restr.replace(/(<head[^>]*)(?:[^])*?\/head>/ig, '')
                .replace(/(<(\/?)body([^>]*?)>)/g, '')
                .replace(/(<style[^>]*)(?:[^])*?\/style>/g, '')
                .replace(/(<(\/?)html([^>]*?)>)/g, '')
                .replace(/(<app-root[^>]*)(?:[^])*?\/app-root>/ig, '')
                .replace(/(<\?[\s\S]*?\?>)|(<!DOCTYPE\s+\w+\s+\[[\s\S]*?\]>)|(<!\w[\s\S]*?>)/g, '')
                .replace(/(href\s*=\s*(?:"))/ig, 'href="/#')
                .replace(/(href\s*=\s*(?:'))/ig, "href='/#");



            this.response = restr;


        })
        .catch(error => this.status = error );

}

你怎么看,这个方法,把response放在变量里,用正则表达式解析字符串 好的,接下来我将它添加到 div 中,就像这样

<div [innerHTML]="response | safe"></div>

很好,我的页面显示出来了。但是,脚本不起作用。它们存在于 div 标签中,但不执行。

我曾尝试用 eval() 来做到这一点,但结果很差

let scripts: string[] = restr.match(/\<scr[\s\S]*?ipt>/g);

            this.srcfield.nativeElement.innerHTML = '';

            scripts.forEach((value, index) => {
                eval.call(null, (this.srcfield.nativeElement.innerHTML = value));
            });

SyntaxError: Unexpected token <

为什么 innerHTML 不执行加载的脚本标签?我该如何解决?

最佳答案

基于 Adam 的解决方案,您可以实现自定义指令以及管道并将脚本重新插入到 DOM 中。这将说明两种情况:内联脚本和“src”脚本。请记住,允许这样的脚本非常危险。

管道:

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

@Pipe({ name: 'safeHtml' })
export class SafeHtmlPipe implements PipeTransform {
    constructor(private sanitizer: DomSanitizer) { }

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

指令:

import { Directive, ElementRef, OnInit } from '@angular/core';

@Directive({ selector: '[runScripts]' })
export class RunScriptsDirective implements OnInit {
    constructor(private elementRef: ElementRef) { }
    ngOnInit(): void {
        setTimeout(() => { // wait for DOM rendering
            this.reinsertScripts();
        });
    }
    reinsertScripts(): void {
        const scripts = <HTMLScriptElement[]>this.elementRef.nativeElement.getElementsByTagName('script');
        const scriptsInitialLength = scripts.length;
        for (let i = 0; i < scriptsInitialLength; i++) {
            const script = scripts[i];
            const scriptCopy = <HTMLScriptElement>document.createElement('script');
            scriptCopy.type = script.type ? script.type : 'text/javascript';
            if (script.innerHTML) {
                scriptCopy.innerHTML = script.innerHTML;
            } else if (script.src) {
                scriptCopy.src = script.src;
            }
            scriptCopy.async = false;
            script.parentNode.replaceChild(scriptCopy, script);
        }
    }
}

用法:

<div [innerHTML]="myDynamicMarkup | safeHtml" runScripts></div>

关于javascript - Angular 2如何从innerHTML执行脚本标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41547505/

相关文章:

javascript - Angular 2 : ViewChild is undefined on parent

javascript - 如何在node.js中同步连接mssql服务器

javascript - CSS关键帧动画不删除显示 block

angular - Http 获取参数过滤器

javascript - 如何在 Angular 数组中添加和删除项目

javascript - anime.js 在 Ionic 3 项目中不起作用

javascript - 单击当前组件时删除类名称同级组件,并在当前组件中进行切换以删除其自身的类

javascript - ExtJs 4 网格分页

apache - 将 IIS 与 Tomcat 集成是个好主意,还是忘记它并坚持使用 Apache HTTP 和 Tomcat

JAVA - 无需应用程序即可自动在 Facebook 墙上发帖