eval() 不执行外部 (src=..) 脚本

eval() doesn't execute external (src=...) scripts

本文关键字:脚本 src 执行 eval 外部      更新时间:2023-09-26

我正在使用eval()在完全重写div(其代码通过XMLHttpRequest加载)后执行所有<script>标签:

var arr = document.getElementById('idOfDIV').getElementsByTagName('script');
         for (var n = 0; n < arr.length; n++){
                try {
                 eval(arr[n].innerHTML);
                } catch(err) {
                console.log(err);
                }
        }

它适用于内联脚本,但对以下脚本没有影响:

<script src="/path/to/externalScript.js"></script>

怎么来了?我可以"强制"浏览器加载和执行外部脚本吗?

注意:正如我所指出的,这个问题可能看起来很"奇怪",关于eval()将字符串作为javascript执行的事实。我需要做的是强制浏览器加载"粘贴"DOM 中包含的外部脚本,并执行它们。

这个标签:

<script src="/path/to/externalScript.js"></script>

有空的 innerHTML,所以你不能评估内容

您可以做的是检查脚本是否具有src属性,并使用此 src 在头部添加一个脚本标签:

function addHeadScript = function(src){
    var head = document.getElementsByTagName("head")[0];
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = src;
    head.appendChild(script);
}
...

for (var n = 0; n < arr.length; n++){
    if (arr[n].src != ""){
        addHeadScript(arr[n].src);
    }
    else {
        // Evaluate the script `innerHTML`   OR
        // Create a script tag in the head and set it's content equal to arr[n].innerHTML
    }
}

你可以做一件事:

var html = "Some html with a script <script>alert('test');</script>";
var frag = parsePartialHtml(html);
fixScriptsSoTheyAreExecuted(frag);

document.body.appendChild(frag);

function fixScriptsSoTheyAreExecuted(el) {
  var scripts = el.querySelectorAll('script'),
      script, fixedScript, i, len;
  for (i = 0, len = scripts.length; i < len; i++) {
    script = scripts[i];
    fixedScript = document.createElement('script');
    fixedScript.type = script.type;
    if (script.innerHTML) fixedScript.innerHTML = script.innerHTML;
    else fixedScript.src = script.src;
    fixedScript.async = false;
    script.parentNode.replaceChild(fixedScript, script);
  }
}

function parsePartialHtml(html) {
  var doc = new DOMParser().parseFromString(html, 'text/html'),
      frag = document.createDocumentFragment(),
      childNodes = doc.body.childNodes;
  while (childNodes.length) frag.appendChild(childNodes[0]);
  return frag;
}