2008-09-16 64 views
34

我工作的一個網頁上,我正在做一個AJAX調用返回HTML像一大塊:你如何執行動態加載的JavaScript塊?

<div> 
    <!-- some html --> 
    <script type="text/javascript"> 
    /** some javascript */ 
    </script> 
</div> 

我將整個事情到DOM,但JavaScript是不正在運行。有沒有辦法來運行它?

一些細節:我無法控制腳本塊中的內容(所以我無法將其更改爲可調用的函數),我只需要執行整個塊。我不能在響應中調用eval,因爲JavaScript在更大的HTML塊內。我可以做一些正則表達式來分離出JavaScript,然後調用eval,但這很糟糕。任何人都知道更好的方法?

回答

14

通過設置元素的innerHTML屬性添加的腳本不會被執行。嘗試創建一個新的div,設置其innerHTML,然後將這個新的div添加到DOM。例如:

 
<html> 
<head> 
<script type='text/javascript'> 
function addScript() 
{ 
    var str = "<script>alert('i am here');<\/script>"; 
    var newdiv = document.createElement('div'); 
    newdiv.innerHTML = str; 
    document.getElementById('target').appendChild(newdiv); 
} 
</script> 
</head> 
<body> 
<input type="button" value="add script" onclick="addScript()"/> 
<div>hello world</div> 
<div id="target"></div> 
</body> 
</html> 
+1

此腳本在IE 7中不起作用.IE 7似乎與appendChild功能有關。 – Eddie 2008-09-26 17:13:48

14

如果您使用響應填充div或其他東西,則不必使用regex。您可以使用getElementsByTagName。

div.innerHTML = response; 
var scripts = div.getElementsByTagName('script'); 
for (var ix = 0; ix < scripts.length; ix++) { 
    eval(scripts[ix].text); 
} 
+7

這似乎很容易受到注入式攻擊和其它病媒... – 2013-06-06 03:40:40

1

最好的方法可能是直接通過DOM來識別和評估腳本塊的內容。

我會小心,雖然..如果你正在實施這個來克服一些異地電話的限制,你正在打開一個安全漏洞。

無論您實施什麼都可以用於XSS。

+0

糾正我,如果我錯了,但我瞭解這種情況下的XSS漏洞,如果您擔心某人能夠訪問他人的在線帳戶,從而能夠竊取敏感信息,但這只是一個問題,但如果用戶無法登錄到該網站然後這不是一個擔心。 – 2015-11-30 19:33:13

2

另一種方法是不只是使用InnerHTML將Ajax調用的返回轉儲到DOM中。

您可以動態插入每個節點,然後腳本將運行。

否則,瀏覽器只是假設你插入了一個文本節點,並忽略了腳本。

使用Eval是相當邪惡的,因爲它需要啓動Javascript VM的另一個實例並將JIT傳遞的字符串。

+12

如果你解釋如何動態插入每個節點,這將是非常好的。 – mandza 2014-06-04 10:53:42

0

您可以使用其中一種常見的Ajax庫,它可以爲您在本地生成這些庫。我喜歡Prototype。您可以添加evalScripts:true作爲Ajax調用的一部分,並且它自動發生。

-1

下面是一個有點不同的方法,它使用的事實,如果標籤包含一個類型=「文本/ XML」的JavaScript內將不會執行:

function preventJS(html) { 
    return html.replace(/<script(?=(\s|>))/i, '<script type="text/xml" '); 
} 

你可以在這裏閱讀更多 - JavaScript: How to prevent execution of JavaScript within a html being added to the DOM。 如果它適合你,請在這裏留下評論,並提供你使用的瀏覽器和版本的信息。

5

雖然從@Ed接受的答案。在當前版本的Firefox,谷歌瀏覽器或Safari瀏覽器中無法正常工作,我設法使用他的示例來調用動態添加的腳本。

必要的更改僅限於將腳本添加到DOM的方式。而不是將其作爲innerHTML添加它的訣竅是創建一個新的腳本元素,並將實際的腳本內容作爲innerHTML添加到創建的元素,然後將腳本元素附加到實際目標。

<html> 
<head> 
<script type='text/javascript'> 
function addScript() 
{ 
    var newdiv = document.createElement('div'); 

    var p = document.createElement('p'); 
    p.innerHTML = "Dynamically added text"; 
    newdiv.appendChild(p); 

    var script = document.createElement('script'); 
    script.innerHTML = "alert('i am here');"; 
    newdiv.appendChild(script); 

    document.getElementById('target').appendChild(newdiv); 
} 
</script> 
</head> 
<body> 
<input type="button" value="add script" onclick="addScript()"/> 
<div>hello world</div> 
<div id="target"></div> 
</body> 
</html> 

這對我的作品在Firefox 42,谷歌Chrome 48和Safari 9.0.3