假设我有以下标记:
<div id="placeHolder"></div>
我有一个JavaScript变量jsVar
,其中包含一些标记和一些JavaScript。
通过使用Mootools 1.1,我可以将JavaScript内容注入占位符,如下所示:
$('placeHolder').setHTML(jsVar);
这适用于Firefox,Opera甚至Safari,结果标记如下:
<div id="placeHolder">
<strong>I was injected</strong>
<script type="text/javascript">
alert("I was injected too!");
</script>
</div>
然而,在IE 8上我得到以下内容:
<div id="placeHolder">
<strong>I was injected</strong>
</div>
有没有办法在IE 8上注入JavaScript或安全模型是否禁止我这样做?
我尝试了Luca Matteis使用
的建议document.getElementById("placeHolder").innerHTML = jsVar;
而不是MooTools代码,我得到相同的结果。这不是MooTools的问题。
答案 0 :(得分:5)
这个MSDN post专门解决了如何使用innerHTML将javascript插入页面。你是对的:IE确实认为这是一个安全问题,所以要求你跳过某些环节来注入脚本...大概是黑客可以读取这个MSDN帖子,所以我不知道如何为什么MS认为这个额外的间接层“安全”,但我离题了。
来自MSDN文章:
<HTML>
<SCRIPT>
function insertScript(){
var sHTML="<input type=button onclick=" + "go2()" + " value='Click Me'><BR>";
var sScript="<SCRIPT DEFER>";
sScript = sScript + "function go2(){ alert('Hello from inserted script.') }";
sScript = sScript + "</SCRIPT" + ">";
ScriptDiv.innerHTML = sHTML + sScript;
}
</SCRIPT>
<BODY onload="insertScript();">
<DIV ID="ScriptDiv"></DIV>
</BODY>
</HTML>
如果可能的话,您可能希望考虑使用document.write
注入的脚本加载标记来提高安全性并减少跨浏览器的不兼容性。我知道这可能是不可能的,但值得考虑。
答案 1 :(得分:4)
这是我们大约一年前在我们的网站上做到这一点,以使其在IE中工作。以下是步骤:
function set_html( id, html ) { // create orphan element set HTML to var orphNode = document.createElement('div'); orphNode.innerHTML = html; // get the script nodes, add them into an arrary, and remove them from orphan node var scriptNodes = orphNode.getElementsByTagName('script'); var scripts = []; while(scriptNodes.length) { // push into script array var node = scriptNodes[0]; scripts.push(node.text); // then remove it node.parentNode.removeChild(node); } // add html to place holder element (note: we are adding the html before we execute the scripts) document.getElementById(id).innerHTML = orphNode.innerHTML; // execute stored scripts var head = document.getElementsByTagName('head')[0]; while(scripts.length) { // create script node var scriptNode = document.createElement('script'); scriptNode.type = 'text/javascript'; scriptNode.text = scripts.shift(); // add the code to the script node head.appendChild(scriptNode); // add it to the page head.removeChild(scriptNode); // then remove it } } set_html('ph', 'this is my html. alert("alert");');
答案 2 :(得分:2)
我遇到过与IE8(和IE7)相同的问题 我可以动态注入脚本(使用src)的唯一方法是使用计时器:
source = "bla.js";
setTimeout(function () {
// run main code
var s = document.createElement('script');
s.setAttribute('src', source);
document.getElementsByTagName('body')[0].appendChild(s);
}, 50);
如果你想要注入内联代码,你可以删除计时器并使用脚本元素的“text”方法:
s.text = "alert('hello world');";
我知道我的答案已经很晚了;然而,迟到总比没有好: - )
答案 3 :(得分:1)
我不确定MooTools,但你尝试过innerHTML吗?
的document.getElementById( “占位符”)。innerHTML的 = jsVar;
答案 4 :(得分:1)
您可能需要评估脚本标记的内容。这需要解析才能在jsVar和eval(whatsBetweenTheScriptTags)中找到脚本。
答案 5 :(得分:1)
由于IE默认情况下拒绝插入内容,你必须自己执行它,但你至少可以欺骗IE为你做解析。
只需使用string.replace()
来交换<script>
的所有<textarea class="myScript" style="display:none">
代码,同时保留内容。然后将结果粘贴到div的innerHTML
。
完成此操作后,您可以使用
div.getElementsByTagName("textarea")
获取所有textareas,遍历它们并查找您的标记类(在这种情况下为"myScript"
),以及eval(textarea.value)
或(new Function(textarea.value))()
您关注的那些。
答案 6 :(得分:1)
我从未尝试过,只是想到了......你能尝试以下几点:
var script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = '//javascript code here'; // not sure if it works
// OR
script.innerText = '//javascript code here'; // not sure if it works
// OR
script.src = 'my_javascript_file.js';
document.getElementById('placeholder').appendChild(script);
您可以使用相同的技术(DOM)插入HTML标记。
答案 7 :(得分:1)
对不起,也许我在这里遗漏了一些东西 - 但这是一个mootools 1.11问题,你为什么不使用assets.js?
// you can also add a json argument with events, etc.
new Asset.javascript("path-to-script.js", {
onload: function() {
callFuncFromScript();
},
id: "myscript"
});
这不是我们使用框架而不是来重新重新发明轮子的原因之一......
就“其他”内容而言,你是怎么做到的?如果通过Request类,它可以通过使用选项很好地完成你想要的任务:
{
update: $("targetId"),
evalScripts: true,
evalResponse: false
}
答案 8 :(得分:0)
当你说它在其他浏览器中“有用”时,你的意思是你得到alert
弹出消息,或者你只是说<script>
标签进入DOM树吗?
如果您的目标是前者,请注意注入嵌入式<script>
的html的行为与浏览器非常相关。例如,在最新的MooTools中,我可以尝试:
$(element).set('html', '<strong>Foo</strong><script>alert(3)</script>')
我不获取弹出窗口,而不是IE(7),而不是FF(3)(但是我做获取<script>
节点成功进入DOM)。要在所有浏览器中将其转到alert
,您必须按this answer进行操作。
答案 9 :(得分:0)
我的评论确实很晚,但这也是最准确的评论 - 你没有看到<script>
内容运行的原因是因为你没有将defer
属性添加到<script>
标记。 MSDN文章明确指出,您需要这样做才能运行<script>
标记。