2009-02-27 92 views
5

我觉得这个优秀的代码,由aemkei张贴回答这个问题:如何动态加载来自不同域的javascript文件?

  1. How do you dynamically load a javascript file? (Think C’s #include)
  2. Use javascript to inject script references as needed?

您可以编写动态脚本标记 (使用原型):

new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"}); 

这里的问题是我们不知道 何时外部脚本文件是 满载。

我们经常要我们对 非常下一行相关的代码,并喜欢写 类似:

if (iNeedSomeMore){ 
    Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod(); 
    myFancyMethod();      // cool, no need for callbacks! 
} 

有注入脚本 的依赖,而不需要 回调一个聪明的办法。您只需通过同步AJAX请求 拉动 脚本并在全局级别上评估该脚本。

如果使用原型的Script.load 方法是这样的:

var Script = { 
    _loadedScripts: [], 
    include: function(script){ 
    // include script only once 
    if (this._loadedScripts.include(script)){ 
     return false; 
    } 
    // request file synchronous 
    var code = new Ajax.Request(script, { 
     asynchronous: false, method: "GET", 
     evalJS: false, evalJSON: false 
    }).transport.responseText; 
    // eval code on global level 
    if (Prototype.Browser.IE) { 
     window.execScript(code); 
    } else if (Prototype.Browser.WebKit){ 
     $$("head").first().insert(Object.extend(
     new Element("script", {type: "text/javascript"}), {text: code} 
    )); 
    } else { 
     window.eval(code); 
    } 
    // remember included script 
    this._loadedScripts.push(script); 
    } 
}; 

我发现,如果所有的人都在“文件执行的代码不能在IE浏览器:/ /'协议,但它不是问题,因为它的用例涉及真正的Web应用程序。

我试过一次,包括http://www.google-analytics.com/urchin.js谷歌,但从网页之一,但它看起来像它不能请求来自不同域的JavaScript文件。

我们如何动态地添加javascript,就像上面的脚本一样,但是来自另一个域?

回答

1

现代浏览器中的安全模型阻止JavaScript发出跨域请求。这有漏洞(参见互联网开始以来的每个网站漏洞利用),但使用它们不仅仅是一点阴影,它们只是一个时间问题,它们需要打补丁。

+0

我想我们可以通过ajax代理来做到这一点,但是,对于大多数实际使用情况来说,这绝对是合适的答案。 ;-) 谢谢。 – Nordin 2009-04-26 22:51:04

0

雷克斯说的是正确的,尽管HTML5已经添加了跨域消息传递和xhr,这需要您的部分工作,但应该可以实现这一点。唉,他们还没有出现在所有发布的浏览器(我认为safari,firefox和IE的最新测试版支持这些功能中的一些,但我不确定哪些浏览器支持哪个apis)

6

您可以使用onloadonreadystatechange事件来了解何时加载了<script>标记。

var script = new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"}); 

script.onload = script.onreadystatechange = function(){ 
    if (!this.readyState || 
     this.readyState == "loaded" || this.readyState == "complete") { 
     //script is loaded 
    } 
}; 
相关问题