注入外部HTML& JS进入一个页面

时间:2016-11-22 06:01:44

标签: javascript html

我正在尝试构建一些网站管理员可以嵌入其网站的小工具。

网站站长是否可以通过包含这样的脚本来加载此工具?

<script src="http://mysite/widget.js"></script>

我尝试通过在AJAX中加载它然后在主体上执行appendChild()来注入它,它正在以这种方式工作但是JS没有被执行。

要注入的内容:

<div>one div</div>
<script>alert('some js')</script>

widget.js

function load(content) {
  var $body = document.body,
      $div = document.createElement("div");
  $div.id = "widget";
  $div.innerHTML = content; 
  $body.appendChild($div);
}

内容变量包含HTML和JS,但注入时不执行JS。

2 个答案:

答案 0 :(得分:4)

由于您不知道脚本将添加到头部或正文标记的位置 - 因此在执行时,您需要确保DOM已准备就绪,因此:

 function load(content) {

    if (document.readyState === "complete" || document.readyState === "loaded") {
         // manipulate DOM
    } else {
       document.addEventListener('DOMContentLoaded', function() {
        // manipulate DOM
    })
}

此外,由于使用innerHTML添加的脚本元素未执行,因此您必须使用eval或更好地创建类似的脚本:

var s = document.createElement('script');
s.text = "alert(\"hi\");"
document.getElementsByTagName('head')[0].appendChild(s);

但是,添加<script>标记以在模板中执行某些脚本是没有意义的,因为当您添加DOM时脚本已经在运行,因此请在那里进行所有必要的设置。

答案 1 :(得分:2)

更新

请参阅Maximus的回答。

是的,出于安全考虑,默认的本机innerHTML不会执行js。

jQuery或zepto $ .fn.append()可以满足您的需求,这就是原因(来自zepto源代码)

if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
           (!el.type || el.type === 'text/javascript') && !el.src)
          window['eval'].call(window, el.innerHTML)

你可以在$ .fn.append函数中看到它是否是一个脚本,如果是,它将使用eval来运行内容。您可能需要eval,但要小心,因为一些网站管理员可能会提供“恶意代码”