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

Posted

技术标签:

【中文标题】eval() 不执行外部 (src=...) 脚本【英文标题】:eval() doesn't execute external (src=...) scripts 【发布时间】:2015-03-22 13:41:57 【问题描述】:

我正在使用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 中的外部脚本,并执行它们。

【问题讨论】:

嗯,你不能这样做,因为脚本标签在 HTML 中没有源代码。您可以再次添加脚本标签,但这可能会导致大量泄漏。 记住:eval() 是邪恶的 我不清楚您要做什么——eval() 将字符串作为可执行的 JavaScript 代码运行,它对 HTML 标记没有任何作用。如果您使用的是 jQuery,我建议您使用 $.getScript() 方法。 @Logard:我知道;但在这种情况下是我唯一的选择。 @Blazemonger:你说得对,我正在用注释更新问题 【参考方案1】:

这个标签:

<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
    

【讨论】:

【参考方案2】:

这是你可以做的一件事:

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;

【讨论】:

以上是关于eval() 不执行外部 (src=...) 脚本的主要内容,如果未能解决你的问题,请参考以下文章

如何在shell脚本中执行cd命令

如何利用shell脚本中的eval命令来构造&quot;智能&quot;命令

eval

js高级一

两周自制脚本语言-第6天 通过解释器执行程序

Shell脚本eval``和$()[[和[ $(( ))