简体   繁体   English

将外部HTML和JS注入页面

[英]Inject external HTML & JS into a page

I'm trying to build some small widgets tools that webmasters can embed in their websites. 我正在尝试构建一些网站管理员可以嵌入其网站的小工具。

Is there any way that the webmaster can simply load this tool by including a script like this? 网站管理员是否可以通过包含这样的脚本来简单地加载此工具?

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

I tried to inject it by loading it in AJAX and then do an appendChild() on the body, it's working this way but the JS is not executed. 我尝试通过在AJAX中加载它然后在body上执行appendChild()来注入它,它正在以这种方式工作但是JS没有被执行。

Content to be injected: 要注入的内容:

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

widget.js widget.js

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

The content variable contains HTML and JS but the JS is not executed when injected. 内容变量包含HTML和JS,但注入时不执行JS。

Since you don't know where you script will be added - to the head or body tag - and consequently when it will be executed, you need to make sure that DOM is ready, so: 由于您不知道脚本将添加到头部或正文标记的位置 - 因此何时执行它,您需要确保DOM已准备就绪,因此:

 function load(content) {

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

Also, since scripts elements added using innerHTML don't get executed, you'd have to either use eval or better create a script like that: 此外,由于使用innerHTML添加的脚本元素不会被执行,您必须使用eval或更好地创建这样的脚本:

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

However, there is no point to add <script> tag to execute some script in your template, since your script is already running when you're adding DOM so do all necessary setups there. 但是,没有必要添加<script>标签来在模板中执行某些脚本,因为在添加DOM时脚本已经运行,因此请在那里进行所有必要的设置。

UPDATE UPDATE

please see Maximus' answer. 请看Maximus的回答。


Right, the default native innerHTML doesn't execute js for safe sake. 是的,出于安全考虑,默认的本机innerHTML不执行js。

jQuery or zepto $.fn.append() can satisfy your need, here is the reason (from zepto source code) 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)

You can see in the function $.fn.append it will see if it's a script, if so it will use eval to run the content. 你可以在$ .fn.append函数中看到它是否是一个脚本,如果是,它将使用eval来运行内容。 You may need eval to, but be careful since some webmasters may deliver 'vice' code 您可能需要eval ,但要小心,因为一些网站管理员可能会提供“恶意”代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM