2009-02-27 40 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 
    } 
};