1

私はボタンを持っています(左側のナビゲーション側)、それをクリックして、右側(コンテンツセクション)にテンプレート(.html)を表示したいと思います。テンプレート(.html)パスはWebサービスからフェッチされ、毎回異なるはずです(ハードコードされた値はありません)。角度2 - bypassSecurityTrustHtml with bypassSecurityTrustScript

そのテンプレート(.html)には独自のスクリプトタグを付けることができます。 Angular 1.xまでは、ng-includeタグでは簡単でしたが、Angular 2はそれをサポートしていないようです。

私は、回避策の下に使用してHTMLのコンテンツ(だけでなく、CSS)を表示することができています -

this.sanitizer.bypassSecurityTrustHtml(url); 

しかし、スクリプトがロードまたは実行取得されていません。

ご協力いただきありがとうございます。

答えて

1

[innerHTML]のオプションは、HTMLコンテンツに単一スクリプトタグがある場合に機能します。しかし、HTMLコンテンツを読み込む複数のスクリプトタグがある場合は、実行可能なオプションではないため、スクリプトをロードして実行する順序を保証するものではありません。そのためには、任意の要素にHTMLを追加し、スクリプトを順番にロードする必要があります。

ソリューション以下

適切にここで説明されている - あなたのHTMLは次のようになります https://ghinda.net/article/script-tags/

- 最初のdivで

<div id="scripts"></div> 
<div id="content"></div> 

、すべてのスクリプトが追加されます第二に、すべてのHTMLコンテンツがなります添付。

最初にHTMLを文字列に変換し、すべてのスクリプトタグをscriptArr []にプッシュします。

// run the scripts inside the dom node 

    if (scriptArr.length > 0) { 
     var $container = document.getElementById('scripts') 
     $container.innerHTML = scriptArr 
     runScripts($container) 
    } 

/* helpers */ 

// runs an array of async functions in sequential order 
function seq(arr, callback, index) { 
    // first call, without an index 
    if (typeof index === 'undefined') { 
     index = 0 
    } 

    arr[index](function() { 
     index++ 
     if (index === arr.length) { 
      callback() 
     } else { 
      seq(arr, callback, index) 
     } 
    }) 
} 

// trigger DOMContentLoaded 
function scriptsDone() { 
    var DOMContentLoadedEvent = document.createEvent('Event') 
    DOMContentLoadedEvent.initEvent('DOMContentLoaded', true, true) 
    document.dispatchEvent(DOMContentLoadedEvent) 
} 

/* script runner */ 

function insertScript($script, callback) { 
    var s = document.createElement('script') 
    if (!s.type) { 
     s.type = 'text/javascript' 
    } 
    if ($script.src) { 
     s.onload = callback 
     s.onerror = callback 
     s.src = $script.src 
    } else { 
     s.textContent = $script.innerText 
    } 

    // re-insert the script tag so it executes. 
    document.head.appendChild(s) 

    // clean-up 
    $script.parentNode.removeChild($script) 

    // run the callback immediately for inline scripts 
    if (!$script.src) { 
     callback() 
    } 
} 

// https://html.spec.whatwg.org/multipage/scripting.html 
var runScriptTypes = [ 
      'application/javascript', 
      'application/ecmascript', 
      'application/x-ecmascript', 
      'application/x-javascript', 
      'text/ecmascript', 
      'text/javascript', 
      'text/javascript1.0', 
      'text/javascript1.1', 
      'text/javascript1.2', 
      'text/javascript1.3', 
      'text/javascript1.4', 
      'text/javascript1.5', 
      'text/jscript', 
      'text/livescript', 
      'text/x-ecmascript', 
      'text/x-javascript' 
     ] 

function runScripts($container) { 
    // get scripts tags from a node 
    var $scripts = $container.querySelectorAll('script') 
    var runList = [] 
    var typeAttr 

    [].forEach.call($scripts, function ($script) { 
     typeAttr = $script.getAttribute('type') 

     // only run script tags without the type attribute 
     // or with a javascript mime attribute value 
     if (!typeAttr || (runScriptTypes ? runScriptTypes.indexOf(typeAttr) !== -1 : 'text/javascript')) { 
      runList.push(function (callback) { 
       insertScript($script, callback) 
      }) 
     } 
    }) 

    // insert the script tags sequentially 
    // to preserve execution order 
    seq(runList, scriptsDone) 
} 

let fragment = document.createRange() 
    .createContextualFragment(html); 

// fragment.baseURI = 'http://toolsqaplp/publish/Dev_Testing/n1d/DS_MAC/en/CATMMGSkillets_en.edu/CATMMGEdc0020_en.doc/src/'; 
document.getElementById('content') 
    .appendChild(fragment); 
+0

回答ありがとうございます。 – kkok

0

official documentは、あなたのケースではbypassSecurityTrustHtml()が動作するはずだと言います。

また、[innerHTML]属性を使用してターゲットコンテナの内容を入力する必要があると仮定しています。

私は、1つのスクリプトタグで1つのHTMLタグが必要な、同様のリユエントメントを持っていました。私はbypassSecurityTrustResourceUrl()を使っていました。

return this.sanitizer.bypassSecurityTrustResourceUrl(url) 

実行可能なソースを取得しているので、あなたのケースでもうまくいくことは間違いありません。

また、combimation bypassSecurityTrustScript()bypassSecurityTrustHtml()を試すこともできます。