2017-01-09 2 views
2

http.get()メソッドでHTMLページを読み込み、このページの内容をdivタグに追加します。あなたが見る、このメソッドは、変数に応答を入れて、正規表現で文字列を解析 [OK]を、次の私は、良い本角2 innerHTMLからスクリプトタグを実行する方法

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

のように、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); 

} 

ページが表示されます。しかし、スクリプトは機能しません。それらはdivタグに存在しますが、実行されません。私が試した

eval()でそれを行うが、innerHTMLがロードされたスクリプトタグを実行しません。なぜこれが悪い

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 <

で終了しますか?どのように私はそれを修正することができます?テンプレートで

答えて

2

、あなたが何か設定することができます。

:対応するコンポーネントで

<div #htmlContainer [innerHTML]="trustedHTML"></div> 

を、あなたはスクリプトタグの配列、およびeval各1を構築、テンプレートにあなたのHTMLを読み込むことができます

@ViewChild('htmlContainer') container; 

ngOnInit() { 
    this.http.get('html-file.html').subscribe((res: Response) => { 
    this.trustedHTML = this.sanitizer.bypassSecurityTrustHtml(res.text()); 

    setTimeout(() => { //wait for DOM rendering 
     let scripts = this.container.nativeElement.getElementsByTagName('script'); 
     for (let script of scripts){ 
     eval(script.text) 
     } 
    }) 

    }); 

私はそう一見単純な何かのためにsetTimeoutevalを使用してに頼らなければならないことを憎むが、それは動作します。

... <script src="...ではありません。私はjQueryのインポートを終了し、$(parent).load(url);を使用しました。誰かが純粋な角度の解決策を持っている場合は、投稿してください。

1

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> 
関連する問題